diff --git a/CMakeLists.txt b/CMakeLists.txt index eaff720d46..c83db79fcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -309,6 +309,7 @@ if (NOT ANDROID AND NOT WEBGL) # must come first because of glslang add_subdirectory(${EXTERNAL}/spirv-tools) + add_subdirectory(${EXTERNAL}/astcenc/tnt) add_subdirectory(${EXTERNAL}/getopt) add_subdirectory(${EXTERNAL}/glslang/tnt) add_subdirectory(${EXTERNAL}/imgui/tnt) diff --git a/libs/imageio/CMakeLists.txt b/libs/imageio/CMakeLists.txt index 175075af5c..975e15cfab 100644 --- a/libs/imageio/CMakeLists.txt +++ b/libs/imageio/CMakeLists.txt @@ -28,7 +28,7 @@ add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS}) target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR}) -target_link_libraries(${TARGET} PUBLIC image math png tinyexr utils z) +target_link_libraries(${TARGET} PUBLIC image math png tinyexr utils z astcenc) if (WIN32) target_link_libraries(${TARGET} PRIVATE wsock32) endif() diff --git a/third_party/astcenc/LICENSE b/third_party/astcenc/LICENSE new file mode 100644 index 0000000000..a33bccd57e --- /dev/null +++ b/third_party/astcenc/LICENSE @@ -0,0 +1,137 @@ +END USER LICENCE AGREEMENT FOR THE MALI ASTC SPECIFICATION AND SOFTWARE CODEC, +VERSION: 1.3 + +THIS END USER LICENCE AGREEMENT ("LICENCE") IS A LEGAL AGREEMENT BETWEEN YOU +(EITHER A SINGLE INDIVIDUAL, OR SINGLE LEGAL ENTITY) AND ARM LIMITED ("ARM") +FOR THE USE OF THE SOFTWARE ACCOMPANYING THIS LICENCE. ARM IS ONLY WILLING +TO LICENSE THE SOFTWARE TO YOU ON CONDITION THAT YOU ACCEPT ALL OF THE TERMS +IN THIS LICENCE. BY CLICKING "I AGREE" OR BY INSTALLING OR OTHERWISE USING +OR COPYING THE SOFTWARE YOU INDICATE THAT YOU AGREE TO BE BOUND BY ALL THE +TERMS OF THIS LICENCE. + +IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENCE, ARM IS UNWILLING TO LICENSE +THE SOFTWARE TO YOU AND YOU MAY NOT INSTALL, USE OR COPY THE SOFTWARE. + +1. DEFINITIONS. + +"Authorised Purpose" means the use of the Software solely to develop products +and tools which implement the Khronos ASTC specification to; +(i) compress texture images into ASTC format ("Compression Results"); +(ii) distribute such Compression Results to third parties; and +(iii) decompress texture images stored in ASTC format. + +"Software" means the source code and Software binaries accompanying this +Licence, and any printed, electronic or online documentation supplied with it, +in all cases relating to the MALI ASTC SPECIFICATION AND SOFTWARE CODEC. + +2. LICENCE GRANT. + +ARM hereby grants to you, subject to the terms and conditions of this Licence, +a nonexclusive, nontransferable, free of charge, royalty free, worldwide +licence to use, copy, modify and (subject to Clause 3 below) distribute the +Software solely for the Authorised Purpose. + +No right is granted to use the Software to develop hardware. + +Notwithstanding the foregoing, nothing in this Licence prevents you from +using the Software to develop products that conform to an application +programming interface specification issued by The Khronos Group Inc. +("Khronos"), provided that you have licences to develop such products +under the relevant Khronos agreements. + + 3. RESTRICTIONS ON USE OF THE SOFTWARE. + +RESTRICTIONS ON TRANSFER OF LICENSED RIGHTS: The rights granted to you under +this Licence may not be assigned by you to any third party without the prior +written consent of ARM. + +TITLE AND RESERVATION OF RIGHTS: You acquire no rights to the Software other +than as expressly provided by this Licence. The Software is licensed not sold. +ARM does not transfer title to the Software to you. In no event shall the +licences granted in Clause 2 be construed as granting you expressly or by +implication, estoppel or otherwise, licences to any ARM technology other than +the Software. + +NOTICES: You shall not remove from the Software any copyright notice or other +notice (whether ARM's or its licensor's), and you shall ensure that any such +notice is reproduced in any copies of the whole or any part of the Software +made by you. You shall not use ARM's or its licensor's name, logo or +trademarks to market Compression Results. If you distribute the Software to a +third party, you agree to include a copy of this Licence with such +distribution. + +4. NO SUPPORT. + +ARM has no obligation to support or to continue providing or updating any of +the Software. + +5. NO WARRANTIES. + +YOU AGREE THAT THE SOFTWARE IS LICENSED "AS IS", AND THAT ARM EXPRESSLY +DISCLAIMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS OR OTHER TERMS, EXPRESS, +IMPLIED OR STATUTORY, TO THE FULLEST EXTENT PERMITTED BY LAW. YOU EXPRESSLY +ASSUME ALL LIABILITIES AND RISKS, FOR USE OR OPERATION OF ANY APPLICATION +PROGRAMS YOU CREATE WITH THE SOFTWARE, AND YOU ASSUME THE ENTIRE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +6. LIMITATION OF LIABILITY. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL ARM BE +LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +(INCLUDING LOSS OF PROFITS) ARISING OUT OF THE USE OR INABILITY TO USE THE +SOFTWARE WHETHER BASED ON A CLAIM UNDER CONTRACT, TORT OR OTHER LEGAL THEORY, +EVEN IF ARM WAS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +ARM does not seek to limit or exclude liability for death or personal injury +arising from ARM's negligence and because some jurisdictions do not permit the +exclusion or limitation of liability for consequential or incidental damages +the above limitation relating to liability for consequential damages may not +apply to you. + +NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED IN THIS LICENCE, THE +MAXIMUM LIABILITY OF ARM TO YOU IN AGGREGATE FOR ALL CLAIMS MADE AGAINST ARM +IN CONTRACT TORT OR OTHERWISE UNDER OR IN CONNECTION WITH THE SUBJECT MATTER +OF THIS LICENCE SHALL NOT EXCEED THE GREATER OF THE TOTAL OF SUMS PAID BY YOU +TO ARM (IF ANY) FOR THIS LICENCE AND US$5.00. + +7. U.S. GOVERNMENT END USERS. + +US Government Restrictions: Use, duplication, reproduction, release, +modification, disclosure or transfer of this commercial product and +accompanying documentation is restricted in accordance with the terms +of this Licence. + +8. TERM AND TERMINATION. + +This Licence shall remain in force until terminated by you or by ARM. Without +prejudice to any of its other rights if you are in breach of any of the terms +and conditions of this Licence then ARM may terminate this Licence immediately +upon giving written notice to you. You may terminate this Licence at any time. + +Upon termination of this Licence by you or by ARM you shall stop using the +Software and destroy all copies of the Software in your possession together +with all documentation and related materials. The provisions of Clauses 1, 3, +4, 5, 6, 7, 8 and 9 shall survive termination of this Licence. + +9. GENERAL. + +This Licence is governed by English Law. Except where ARM agrees otherwise in +a written contract signed by you and ARM, this is the only agreement between +you and ARM relating to the Software and it may only be modified by written +agreement between you and ARM. Except as expressly agreed in writing, this +Licence may not be modified by purchase orders, advertising or other +representation by any person. If any clause in this Licence is held by a court +of law to be illegal or unenforceable the remaining provisions of this Licence +shall not be affected thereby. The failure by ARM to enforce any of the +provisions of this Licence, unless waived in writing, shall not constitute a +waiver of ARM's rights to enforce such provision or any other provision of +this Licence in the future. + +You agree to comply fully with all laws and regulations of the United States +and other countries ("Export Laws") to assure that the Software is not; +(1) exported, directly or indirectly, in violation of Export Laws, either to +any countries that are subject to U.S.A. export restrictions or to any end +user who has been prohibited from participating in the U.S.A. export +transactions by any federal agency of the U.S.A. government; or +(2) intended to be used for any purpose prohibited by Export Laws, including, +without limitation, nuclear, chemical, or biological weapons proliferation. diff --git a/third_party/astcenc/README.md b/third_party/astcenc/README.md new file mode 100644 index 0000000000..1c9c825958 --- /dev/null +++ b/third_party/astcenc/README.md @@ -0,0 +1,108 @@ +# About + +This is the official repository of the evaluation codec for the Adaptive Scalable Texture Compression (ASTC) standard. + +ASTC technology developed by ARM® and AMD has been adopted as an official extension to both the Open GL® and OpenGL ES graphics APIs. ASTC is a major step forward in terms of image quality, reducing memory bandwidth and thus energy use. + +The **ASTC Evaluation Codec** is a command-line executable that compresses and decompresses images using this texture compression standard. + +Running on a standard PC, this tool allows content developers to evaluate the impressive quality and size benefits offered by this texture compression format, in advance of it being available in GPU hardware. + +# License # +By downloading the packages below you ackowledge that you accept the End User Licence Agreement for the ATSC Codec. +See [license.txt](license.txt) file for details. + +# Compilation from Sources +* You can use GCC >= 4.6 and standard GNU tools to perform make-driven compilation on Linux and/or MacOS systems. +* You can use Visual Studio 2013 to compile for Windows systems (using solution file from `Source/win32-2013/astcenc` directory). + +# ASTC Features & Benefits + +ASTC offers a number of advantages over existing texture compression schemes: + +* Flexibility, with bit rates from 8 bits per pixel (bpp) down to less than 1 bpp. This allows content developers to fine-tune the tradeoff of space against quality. +* Support for 1 to 4 color channels, together with modes for uncorrelated channels for use in mask textures and normal maps. +* Support for both low dynamic range (LDR) and high dynamic range (HDR) images. +* Support for both 2D and 3D images. +* Interoperability: Developers can choose any combination of features that suits their needs. + +ASTC specification includes two profiles: LDR and Full. The smaller LDR Profile supports 2D low dynamic range images only. It is designed to be easy to integrate with existing hardware designs that already deal with compressed 2D images in other formats. The LDR Profile is a strict subset of the Full Profile, which also includes the 3D textures and high dynamic range support. + +## Encoding + +* Compression of PNG, TGA and KTX into ASTC format +* Control of bit rate from 0.89 bits/pixel upto 8bits/pixel in fine steps +* Control of compression time/quality tradeoff with exhaustive, thorough, medium, fast and very fast encoding speeds +* Supports both low (LDR) and high dynamic range (HDR) images +* Supports 3D texture compression +* Measure PSNR between input and output + +## Decoding + +* Decodes ASTC images to TGA or KTX + +# Package Contents + +* Source code +* Full specification of the ASTC data format +* Binaries for Windows, Mac OS X and Linux + +# Getting Started + +First, accept the [license](license.txt) and download the source code. The `Binary` subdirectory contains executable binaries for Windows, Mac OS X, and Linux. If you are running on another system, you might like to try compiling from source. + +Open a terminal, change to the appropriate directory for your system, and run the astcenc encoder program, like this on Linux or Mac OS: + + ./astcenc + +Or like this on Windows: + + astcenc + +Invoking the tool with no arguments gives a very extensive help message, including usage instructions, and details of all the possible options. + +## How do I run the tool? + +First, find a 24-bit .png or .tga file you wish to use, say `/images/example.png` (or on Windows `C:\images\example.png`). + +You can compress it using the `-c` option, like this (on Linux or Mac OS X): + + ./astcenc -c /images/example.png /images/example-compressed.astc 6x6 -medium + +and on Windows: + + astcenc -c C:\images\example.png C:\images\example-compressed.astc 6x6 -medium + +The `-c` indicates a compression operation, followed by the input and output filenames. The block footprint size follows, in this case 6x6 pixels, then the requested compression speed, medium. + +To decompress the file again, you should use: + + ./astcenc -d /images/example-compressed.astc /images/example-decompressed.tga + +and on Windows: + + astcenc -d C:\images\example-compressed.astc C:\images\example-decompressed.tga + +The `-d` indicates decompression, followed by the input and output filenames. The output file will be an uncompressed TGA image. + +If you just want to test what compression and decompression are like, use the test mode: + + ./astcenc -t /images/example.png /images/example-decompressed.tga 6x6 -medium + +and on Windows: + + astcenc -t C:\images\example.png C:\images\example-compressed.tga 6x6 -medium + +This is equivalent to compressing and then immediately decompressing again, and it also prints out statistics about the fidelity of the resulting image, using the peak signal-to-noise ratio. + +## Experimenting + +The block footprints go from 4x4 (8 bits per pixel) all the way up to 12x12 (0.89 bits/pixel). Like any lossy codec, such as JPEG there will come a point where selecting too aggressive a compression results in inacceptable quality loss, and ASTC is no exception. Finding this optimum balance between size and quality is one place where ASTC excels since its compression ratio is adjustable in much finer steps than other texture codecs. + +The compression speed runs from `-veryfast`, through `-fast`, `-medium` and `-thorough`, up to `-exhaustive`. In general, the more time the encoder has to spend looking for good encodings, the better the results. + +# Support +Please submit your questions and issues to the [ARM Mali Graphics forums](http://community.arm.com/groups/arm-mali-graphics). + +- - - +_Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved._ diff --git a/third_party/astcenc/Source/Makefile b/third_party/astcenc/Source/Makefile new file mode 100644 index 0000000000..298a4f77a9 --- /dev/null +++ b/third_party/astcenc/Source/Makefile @@ -0,0 +1,73 @@ +#---------------------------------------------------------------------------- +# +# This confidential and proprietary software may be used only as +# authorised by a licensing agreement from ARM Limited +# (C) COPYRIGHT 2011-2012 ARM Limited +# ALL RIGHTS RESERVED +# +# The entire notice above must be reproduced on all authorised +# copies and copies may only be made to the extent permitted +# by a licensing agreement from ARM Limited. +# +# @brief Make file to build ASTC codec. +# +#---------------------------------------------------------------------------- + +SOURCES = \ + astc_averages_and_directions.cpp \ + astc_block_sizes2.cpp \ + astc_color_quantize.cpp \ + astc_color_unquantize.cpp \ + astc_compress_symbolic.cpp \ + astc_decompress_symbolic.cpp \ + astc_encoding_choice_error.cpp \ + astc_find_best_partitioning.cpp \ + astc_ideal_endpoints_and_weights.cpp \ + astc_image_load_store.cpp \ + astc_integer_sequence.cpp \ + astc_ktx_dds.cpp \ + astc_kmeans_partitioning.cpp \ + astc_partition_tables.cpp \ + astc_percentile_tables.cpp \ + astc_pick_best_endpoint_format.cpp \ + astc_quantization.cpp \ + astc_stb_tga.cpp \ + astc_symbolic_physical.cpp \ + astc_weight_align.cpp \ + astc_weight_quant_xfer_tables.cpp \ + astc_compute_variance.cpp \ + astc_toplevel.cpp \ + mathlib.cpp \ + softfloat.cpp \ + + +HEADERS = \ + astc_codec_internals.h \ + mathlib.h \ + softfloat.h \ + stb_image.c + + +OBJECTS = $(SOURCES:.cpp=.o) + + +CPPFLAGS = -O3 -Wall -W -Wextra -msse2 -mfpmath=sse + + +astcenc: $(OBJECTS) stb_image.o + g++ -o $@ $^ $(CPPFLAGS) -lpthread + + +$(OBJECTS): %.o: %.cpp $(HEADERS) + g++ -c -o $@ $< $(CPPFLAGS) + + +stb_image.o: stb_image.c + g++ -c -o $@ $< $(CPPFLAGS) + + +clean: + rm -f *.o + rm -f *.obj + rm -f astcenc + rm -f astcenc.exe diff --git a/third_party/astcenc/Source/astc_averages_and_directions.cpp b/third_party/astcenc/Source/astc_averages_and_directions.cpp new file mode 100644 index 0000000000..ece97d07fb --- /dev/null +++ b/third_party/astcenc/Source/astc_averages_and_directions.cpp @@ -0,0 +1,627 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Implements functions for finding dominant direction of a set of + * colors, using ARM patent pending method. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include +#include "mathlib.h" + +#ifdef DEBUG_CAPTURE_NAN + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + + #include +#endif + +/* routines to compute average colors and dominant directions for blocks with 3 and 4 components. */ + +/* + for a full block, functions to compute averages and dominant directions. The averages and directions are computed separately for each partition. + We have separate versions for blocks with and without alpha, since the processing for blocks with alpha is significantly more expensive. + The direction vectors it produces are NOT normalized. +*/ +void compute_averages_and_directions_rgba(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float4 * color_scalefactors, + float4 * averages, float4 * directions_rgba, float3 * directions_gba, float3 * directions_rba, float3 * directions_rga, float3 * directions_rgb) +{ + int i; + int partition_count = pt->partition_count; + int partition; + + for (partition = 0; partition < partition_count; partition++) + { + const uint8_t *weights = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + + float4 base_sum = float4(0, 0, 0, 0); + float partition_weight = 0.0f; + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = ewb->texel_weight[iwt]; + float4 texel_datum = float4(blk->work_data[4 * iwt], + blk->work_data[4 * iwt + 1], + blk->work_data[4 * iwt + 2], + blk->work_data[4 * iwt + 3]) * weight; + partition_weight += weight; + + base_sum = base_sum + texel_datum; + } + + float4 average = base_sum * 1.0f / MAX(partition_weight, 1e-7f); + averages[partition] = average * color_scalefactors[partition]; + + + float4 sum_xp = float4(0, 0, 0, 0); + float4 sum_yp = float4(0, 0, 0, 0); + float4 sum_zp = float4(0, 0, 0, 0); + float4 sum_wp = float4(0, 0, 0, 0); + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = ewb->texel_weight[iwt]; + float4 texel_datum = float4(blk->work_data[4 * iwt], + blk->work_data[4 * iwt + 1], + blk->work_data[4 * iwt + 2], + blk->work_data[4 * iwt + 3]); + texel_datum = (texel_datum - average) * weight; + + if (texel_datum.x > 0.0f) + sum_xp = sum_xp + texel_datum; + if (texel_datum.y > 0.0f) + sum_yp = sum_yp + texel_datum; + if (texel_datum.z > 0.0f) + sum_zp = sum_zp + texel_datum; + if (texel_datum.w > 0.0f) + sum_wp = sum_wp + texel_datum; + } + + float prod_xp = dot(sum_xp, sum_xp); + float prod_yp = dot(sum_yp, sum_yp); + float prod_zp = dot(sum_zp, sum_zp); + float prod_wp = dot(sum_wp, sum_wp); + + float4 best_vector = sum_xp; + float best_sum = prod_xp; + if (prod_yp > best_sum) + { + best_vector = sum_yp; + best_sum = prod_yp; + } + if (prod_zp > best_sum) + { + best_vector = sum_zp; + best_sum = prod_zp; + } + if (prod_wp > best_sum) + { + best_vector = sum_wp; + best_sum = prod_wp; + } + + directions_rgba[partition] = best_vector; + directions_rgb[partition] = best_vector.xyz; + directions_rga[partition] = best_vector.xyw; + directions_rba[partition] = best_vector.xzw; + directions_gba[partition] = best_vector.yzw; + } +} + + + + +void compute_averages_and_directions_rgb(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float4 * color_scalefactors, float3 * averages, float3 * directions_rgb, float2 * directions_rg, float2 * directions_rb, float2 * directions_gb) +{ + int i; + int partition_count = pt->partition_count; + int partition; + + const float *texel_weights = ewb->texel_weight_rgb; + + for (partition = 0; partition < partition_count; partition++) + { + const uint8_t *weights = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + + float3 base_sum = float3(0, 0, 0); + float partition_weight = 0.0f; + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = texel_weights[iwt]; + float3 texel_datum = float3(blk->work_data[4 * iwt], + blk->work_data[4 * iwt + 1], + blk->work_data[4 * iwt + 2]) * weight; + partition_weight += weight; + + base_sum = base_sum + texel_datum; + } + + float4 csf = color_scalefactors[partition]; + float3 average = base_sum * 1.0f / MAX(partition_weight, 1e-7f); + averages[partition] = average * csf.xyz; + + + float3 sum_xp = float3(0, 0, 0); + float3 sum_yp = float3(0, 0, 0); + float3 sum_zp = float3(0, 0, 0); + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = texel_weights[iwt]; + float3 texel_datum = float3(blk->work_data[4 * iwt], + blk->work_data[4 * iwt + 1], + blk->work_data[4 * iwt + 2]); + texel_datum = (texel_datum - average) * weight; + + if (texel_datum.x > 0.0f) + sum_xp = sum_xp + texel_datum; + if (texel_datum.y > 0.0f) + sum_yp = sum_yp + texel_datum; + if (texel_datum.z > 0.0f) + sum_zp = sum_zp + texel_datum; + } + + float prod_xp = dot(sum_xp, sum_xp); + float prod_yp = dot(sum_yp, sum_yp); + float prod_zp = dot(sum_zp, sum_zp); + + float3 best_vector = sum_xp; + float best_sum = prod_xp; + if (prod_yp > best_sum) + { + best_vector = sum_yp; + best_sum = prod_yp; + } + if (prod_zp > best_sum) + { + best_vector = sum_zp; + best_sum = prod_zp; + } + + directions_rgb[partition] = best_vector; + directions_gb[partition] = best_vector.yz; + directions_rb[partition] = best_vector.xz; + directions_rg[partition] = best_vector.xy; + } +} + +void compute_averages_and_directions_3_components(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float3 * color_scalefactors, int component1, int component2, int component3, float3 * averages, float3 * directions) +{ + int i; + int partition_count = pt->partition_count; + int partition; + + const float *texel_weights; + if (component1 == 1 && component2 == 2 && component3 == 3) + texel_weights = ewb->texel_weight_gba; + else if (component1 == 0 && component2 == 2 && component3 == 3) + texel_weights = ewb->texel_weight_rba; + else if (component1 == 0 && component2 == 1 && component3 == 3) + texel_weights = ewb->texel_weight_rga; + else if (component1 == 0 && component2 == 1 && component3 == 2) + texel_weights = ewb->texel_weight_rgb; + else + { + texel_weights = ewb->texel_weight_gba; + ASTC_CODEC_INTERNAL_ERROR; + } + + + for (partition = 0; partition < partition_count; partition++) + { + const uint8_t *weights = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + + float3 base_sum = float3(0, 0, 0); + float partition_weight = 0.0f; + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = texel_weights[iwt]; + float3 texel_datum = float3(blk->work_data[4 * iwt + component1], + blk->work_data[4 * iwt + component2], + blk->work_data[4 * iwt + component3]) * weight; + partition_weight += weight; + + base_sum = base_sum + texel_datum; + } + + float3 csf = color_scalefactors[partition]; + + float3 average = base_sum * 1.0f / MAX(partition_weight, 1e-7f); + averages[partition] = average * csf.xyz; + + + float3 sum_xp = float3(0, 0, 0); + float3 sum_yp = float3(0, 0, 0); + float3 sum_zp = float3(0, 0, 0); + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = texel_weights[iwt]; + float3 texel_datum = float3(blk->work_data[4 * iwt + component1], + blk->work_data[4 * iwt + component2], + blk->work_data[4 * iwt + component3]); + texel_datum = (texel_datum - average) * weight; + + if (texel_datum.x > 0.0f) + sum_xp = sum_xp + texel_datum; + if (texel_datum.y > 0.0f) + sum_yp = sum_yp + texel_datum; + if (texel_datum.z > 0.0f) + sum_zp = sum_zp + texel_datum; + } + + float prod_xp = dot(sum_xp, sum_xp); + float prod_yp = dot(sum_yp, sum_yp); + float prod_zp = dot(sum_zp, sum_zp); + + float3 best_vector = sum_xp; + float best_sum = prod_xp; + if (prod_yp > best_sum) + { + best_vector = sum_yp; + best_sum = prod_yp; + } + if (prod_zp > best_sum) + { + best_vector = sum_zp; + best_sum = prod_zp; + } + + if (dot(best_vector, best_vector) < 1e-18) + best_vector = float3(1, 1, 1); + directions[partition] = best_vector; + } + +} + + + + +void compute_averages_and_directions_2_components(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, const float2 * color_scalefactors, int component1, int component2, float2 * averages, float2 * directions) +{ + int i; + int partition_count = pt->partition_count; + int partition; + + const float *texel_weights; + if (component1 == 0 && component2 == 1) + texel_weights = ewb->texel_weight_rg; + else if (component1 == 0 && component2 == 2) + texel_weights = ewb->texel_weight_rb; + else if (component1 == 1 && component2 == 2) + texel_weights = ewb->texel_weight_gb; + else + { + texel_weights = ewb->texel_weight_rg; + // unsupported set of color components. + ASTC_CODEC_INTERNAL_ERROR; + exit(1); + } + + + for (partition = 0; partition < partition_count; partition++) + { + const uint8_t *weights = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + + float2 base_sum = float2(0, 0); + float partition_weight = 0.0f; + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = texel_weights[iwt]; + float2 texel_datum = float2(blk->work_data[4 * iwt + component1], + blk->work_data[4 * iwt + component2]) * weight; + partition_weight += weight; + + base_sum = base_sum + texel_datum; + } + + float2 csf = color_scalefactors[partition]; + + float2 average = base_sum * 1.0f / MAX(partition_weight, 1e-7f); + averages[partition] = average * csf.xy; + + + float2 sum_xp = float2(0, 0); + float2 sum_yp = float2(0, 0); + + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float weight = texel_weights[iwt]; + float2 texel_datum = float2(blk->work_data[4 * iwt + component1], + blk->work_data[4 * iwt + component2]); + texel_datum = (texel_datum - average) * weight; + + if (texel_datum.x > 0.0f) + sum_xp = sum_xp + texel_datum; + if (texel_datum.y > 0.0f) + sum_yp = sum_yp + texel_datum; + } + + float prod_xp = dot(sum_xp, sum_xp); + float prod_yp = dot(sum_yp, sum_yp); + + float2 best_vector = sum_xp; + float best_sum = prod_xp; + if (prod_yp > best_sum) + { + best_vector = sum_yp; + best_sum = prod_yp; + } + + directions[partition] = best_vector; + } + +} + + +#define XPASTE(x,y) x##y +#define PASTE(x,y) XPASTE(x,y) + +#define TWO_COMPONENT_ERROR_FUNC( funcname, c0_iwt, c1_iwt, c01_name, c01_rname ) \ +float funcname( \ + const partition_info *pt, \ + const imageblock *blk, \ + const error_weight_block *ewb, \ + const processed_line2 *plines, \ + float *length_of_lines \ + ) \ + { \ + int i; \ + float errorsum = 0.0f; \ + int partition; \ + for(partition=0; partitionpartition_count; partition++) \ + { \ + const uint8_t *weights = pt->texels_of_partition[ partition ]; \ + int texelcount = pt->texels_per_partition[ partition ]; \ + float lowparam = 1e10f; \ + float highparam = -1e10f; \ + processed_line2 l = plines[partition]; \ + if( ewb->contains_zeroweight_texels ) \ + { \ + for(i=0;i PASTE(texel_weight_ , c01_rname) [i]; \ + if( texel_weight > 1e-20f ) \ + { \ + float2 point = float2(blk->work_data[4*iwt + c0_iwt], blk->work_data[4*iwt + c1_iwt] ); \ + float param = dot( point, l.bs ); \ + float2 rp1 = l.amod + param*l.bis; \ + float2 dist = rp1 - point; \ + float4 ews = ewb->error_weights[iwt]; \ + errorsum += dot( ews. c01_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + } \ + else \ + { \ + for(i=0;iwork_data[4*iwt + c0_iwt], blk->work_data[4*iwt + c1_iwt] ); \ + float param = dot( point, l.bs ); \ + float2 rp1 = l.amod + param*l.bis; \ + float2 dist = rp1 - point; \ + float4 ews = ewb->error_weights[iwt]; \ + errorsum += dot( ews. c01_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + float linelen = highparam - lowparam; \ + if( !(linelen > 1e-7f) ) \ + linelen = 1e-7f; \ + length_of_lines[partition] = linelen; \ + } \ + return errorsum; \ + } + + +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_rg, 0, 1, xy, rg) +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_rb, 0, 2, xz, rb) +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_gb, 1, 2, yz, gb) +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_ra, 0, 3, zw, ra) + +// function to compute the error across a tile when using a particular set of +// lines for a particular partitioning. Also compute the length of each +// color-space line in each partitioning. + +#define THREE_COMPONENT_ERROR_FUNC( funcname, c0_iwt, c1_iwt, c2_iwt, c012_name, c012_rname ) \ +float funcname( \ + const partition_info *pt, \ + const imageblock *blk, \ + const error_weight_block *ewb, \ + const processed_line3 *plines, \ + float *length_of_lines \ + ) \ + { \ + int i; \ + float errorsum = 0.0f; \ + int partition; \ + for(partition=0; partitionpartition_count; partition++) \ + { \ + const uint8_t *weights = pt->texels_of_partition[ partition ]; \ + int texelcount = pt->texels_per_partition[ partition ]; \ + float lowparam = 1e10f; \ + float highparam = -1e10f; \ + processed_line3 l = plines[partition]; \ + if( ewb->contains_zeroweight_texels ) \ + { \ + for(i=0;i PASTE(texel_weight_ , c012_rname) [i]; \ + if( texel_weight > 1e-20f ) \ + { \ + float3 point = float3(blk->work_data[4*iwt + c0_iwt], blk->work_data[4*iwt + c1_iwt], blk->work_data[4*iwt + c2_iwt] ); \ + float param = dot( point, l.bs ); \ + float3 rp1 = l.amod + param*l.bis; \ + float3 dist = rp1 - point; \ + float4 ews = ewb->error_weights[iwt]; \ + errorsum += dot( ews. c012_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + } \ + else \ + { \ + for(i=0;iwork_data[4*iwt + c0_iwt], blk->work_data[4*iwt + c1_iwt], blk->work_data[4*iwt + c2_iwt] ); \ + float param = dot( point, l.bs ); \ + float3 rp1 = l.amod + param*l.bis; \ + float3 dist = rp1 - point; \ + float4 ews = ewb->error_weights[iwt]; \ + errorsum += dot( ews. c012_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + float linelen = highparam - lowparam; \ + if( !(linelen > 1e-7f) ) \ + linelen = 1e-7f; \ + length_of_lines[partition] = linelen; \ + } \ + return errorsum; \ + } + +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_gba, 1, 2, 3, yzw, gba) +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_rba, 0, 2, 3, xzw, rba) +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_rga, 0, 1, 3, xyw, rga) +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_rgb, 0, 1, 2, xyz, rgb) + +float compute_error_squared_rgba(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line4 * plines, float *length_of_lines) +{ + int i; + + float errorsum = 0.0f; + int partition; + for (partition = 0; partition < pt->partition_count; partition++) + { + const uint8_t *weights = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + float lowparam = 1e10; + float highparam = -1e10; + + processed_line4 l = plines[partition]; + + if (ewb->contains_zeroweight_texels) + { + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + if (ewb->texel_weight[iwt] > 1e-20) + { + float4 point = float4(blk->work_data[4 * iwt], blk->work_data[4 * iwt + 1], blk->work_data[4 * iwt + 2], blk->work_data[4 * iwt + 3]); + float param = dot(point, l.bs); + float4 rp1 = l.amod + param * l.bis; + float4 dist = rp1 - point; + float4 ews = ewb->error_weights[iwt]; + errorsum += dot(ews, dist * dist); + if (param < lowparam) + lowparam = param; + if (param > highparam) + highparam = param; + } + } + } + else + { + for (i = 0; i < texelcount; i++) + { + int iwt = weights[i]; + float4 point = float4(blk->work_data[4 * iwt], blk->work_data[4 * iwt + 1], blk->work_data[4 * iwt + 2], blk->work_data[4 * iwt + 3]); + float param = dot(point, l.bs); + float4 rp1 = l.amod + param * l.bis; + float4 dist = rp1 - point; + float4 ews = ewb->error_weights[iwt]; + errorsum += dot(ews, dist * dist); + if (param < lowparam) + lowparam = param; + if (param > highparam) + highparam = param; + } + } + + float linelen = highparam - lowparam; + if (!(linelen > 1e-7f)) + linelen = 1e-7f; + length_of_lines[partition] = linelen; + } + + return errorsum; +} + + + +// function to compute the error across a tile when using a particular line for +// a particular partition. +float compute_error_squared_rgb_single_partition(int partition_to_test, int xdim, int ydim, int zdim, const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * lin // the line for the partition. + ) +{ + int i; + + int texels_per_block = xdim * ydim * zdim; + + float errorsum = 0.0f; + + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + float texel_weight = ewb->texel_weight_rgb[i]; + if (partition != partition_to_test || texel_weight < 1e-20) + continue; + float3 point = float3(blk->work_data[4 * i], blk->work_data[4 * i + 1], blk->work_data[4 * i + 2]); + + float param = dot(point, lin->bs); + float3 rp1 = lin->amod + param * lin->bis; + float3 dist = rp1 - point; + float4 ews = ewb->error_weights[i]; + + errorsum += dot(ews.xyz, dist * dist); + } + return errorsum; +} diff --git a/third_party/astcenc/Source/astc_averages_and_directions_eigenvectors.cpp b/third_party/astcenc/Source/astc_averages_and_directions_eigenvectors.cpp new file mode 100644 index 0000000000..82137766a2 --- /dev/null +++ b/third_party/astcenc/Source/astc_averages_and_directions_eigenvectors.cpp @@ -0,0 +1,920 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Implements functions for finding dominant direction of a set of + * colors, using eigenvector method + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include +#include "mathlib.h" + +#ifdef DEBUG_CAPTURE_NAN + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + + #include +#endif + + +/* routines to compute average colors and eigenvectors for blocks with 3 and 4 components. */ + + +/* + Methods to compute eigenvectors iteratively. They are used when analytic calculation of eigenvector fails. + + These methods work as follows: + + * square the matrix + * rescale the matrix + + The matrix is rescaled once every two squarings, mainly to protect against possible overflow/underflow situations. + We perform 20 squarings of the matrix, with is equivalent to raising the matrix to the 1048576th power, which should be adequate. + The eigenvector functions are carefully guarded so that they don't produce nullvectors or vectors with NaN in them. +*/ + +static float4 power_method_eigenvector4(const mat4 & q) +{ + mat4 p = q; + int i; + float4 eigvc; + for (i = 0; i < 20; i++) + { + float sc0 = + ((fabs(p.v[0].x) + + fabs(p.v[0].y) + + fabs(p.v[0].z) + + fabs(p.v[0].w)) + + (fabs(p.v[1].x) + + fabs(p.v[1].y) + + fabs(p.v[1].z) + fabs(p.v[1].w))) + ((fabs(p.v[2].x) + fabs(p.v[2].y) + fabs(p.v[2].z) + fabs(p.v[2].w)) + (fabs(p.v[3].x) + fabs(p.v[3].y) + fabs(p.v[3].z) + fabs(p.v[3].w))); + sc0 *= 0.25f; + + // if the matrix is all zeroes or contains NaNs, then get out early. + if (!(sc0 > 0.0f)) + return float4(1, 1, 1, 1); + + sc0 = 1.0f / sc0; + p.v[0] = p.v[0] * sc0; + p.v[1] = p.v[1] * sc0; + p.v[2] = p.v[2] * sc0; + p.v[3] = p.v[3] * sc0; + + p = p * p; + + // after each pair of iterations, check if we have a good enough eigenvector. + eigvc = p.v[0] + p.v[1] + p.v[2] + p.v[3]; + + float4 xform_eigvc = transform(q, eigvc); + float evd = dot(eigvc, eigvc); + float xvd = dot(xform_eigvc, xform_eigvc); + float evx = dot(eigvc, xform_eigvc); + if (evx * evx > evd * xvd * 0.999f) // allow about 1.25 degree deviation + return eigvc; + } + + float testval = fabs(eigvc.x) + fabs(eigvc.y) + fabs(eigvc.z) + fabs(eigvc.w); + if (testval > 1e-18f) + return eigvc; // catch eigenvectors with 0 or NaN in them. + else + return float4(1.0f, 1.0f, 1.0f, 1.0f); +} + + +static float3 power_method_eigenvector3(const mat3 & q) +{ + int i; + mat3 p = q; + float3 eigvc; + + for (i = 0; i < 20; i++) + { + float sc0 = (fabs(p.v[0].x) + fabs(p.v[0].y) + fabs(p.v[0].z)) + (fabs(p.v[1].x) + fabs(p.v[1].y) + fabs(p.v[1].z)) + (fabs(p.v[2].x) + fabs(p.v[2].y) + fabs(p.v[2].z)); + sc0 *= 0.25f; + + // if the matrix is all zeroes or contains NaNs, then get out early. + if (!(sc0 > 0.0f)) + return float3(1, 1, 1); + + sc0 = 1.0f / sc0; + p.v[0] = p.v[0] * sc0; + p.v[1] = p.v[1] * sc0; + p.v[2] = p.v[2] * sc0; + + p = p * p; + + // after each pair of iterations, check if we have a good enough eigenvector. + eigvc = p.v[0] + p.v[1] + p.v[2]; + + float3 xform_eigvc = transform(q, eigvc); + float evd = dot(eigvc, eigvc); + float xvd = dot(xform_eigvc, xform_eigvc); + float evx = dot(eigvc, xform_eigvc); + if (evx * evx > evd * xvd * 0.999f) // allow about 1.25 degree deviation + return eigvc; + + } + + + float testval = fabs(eigvc.x) + fabs(eigvc.y) + fabs(eigvc.z); + if (testval > 1e-18f) + return eigvc; // catch eigenvectors with 0 or NaN in them. + else + return float3(1.0f, 1.0f, 1.0f); +} + + +static float2 power_method_eigenvector2(const mat2 & q) +{ + int i; + mat2 p = q; + float2 eigvc; + for (i = 0; i < 20; i++) + { + float sc0 = (fabs(p.v[0].x) + fabs(p.v[0].y)) + (fabs(p.v[1].x) + fabs(p.v[1].y)); + sc0 *= 0.25f; + if (!(sc0 > 0.0f)) + return float2(1, 1); + + sc0 = 1.0f / sc0; + p.v[0] = p.v[0] * sc0; + p.v[1] = p.v[1] * sc0; + + p = p * p; + + eigvc = p.v[0] + p.v[1]; + float2 xform_eigvc = transform(q, eigvc); + float evd = dot(eigvc, eigvc); + float xvd = dot(xform_eigvc, xform_eigvc); + float evx = dot(eigvc, xform_eigvc); + if (evx * evx > evd * xvd * 0.999f) // allow about 1.25 degree deviation + return eigvc; + } + + float testval = fabs(eigvc.x) + fabs(eigvc.y); + if (testval > 1e-18f) + return eigvc; // catch eigenvectors with 0 or NaN in them. + else + return float2(1.0f, 1.0f); +} + + +static float4 get_eigenvector4(const mat4 & p) +{ + +#ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); +#endif + + float4 eigvls = eigenvalues(p); + float maxval = 0.0f; + // do comparison for every eigenvalue; needed to catch possible NaN-cases. + if (fabs(eigvls.x) > fabs(maxval)) + maxval = eigvls.x; + if (fabs(eigvls.y) > fabs(maxval)) + maxval = eigvls.y; + if (fabs(eigvls.z) > fabs(maxval)) + maxval = eigvls.z; + if (fabs(eigvls.w) > fabs(maxval)) + maxval = eigvls.w; + + float4 retval; + + if (maxval > 0.0f) + { + float4 eigvc = eigenvector(p, maxval); + // check whether the computed eigenvector is in fact a reasonable eigenvector at all. + float4 xform_eigvc = transform(p, eigvc); + float evd = dot(eigvc, eigvc); + float xvd = dot(xform_eigvc, xform_eigvc); + float evx = dot(eigvc, xform_eigvc); + if (evx * evx > evd * xvd * 0.999f) // allow about 1 degree deviation + retval = eigvc; + else + retval = power_method_eigenvector4(p); + } + else + retval = power_method_eigenvector4(p); + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + return retval; +} + + +static float3 get_eigenvector3(const mat3 & p) +{ + +#ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); +#endif + + float3 eigvls = eigenvalues(p); + float maxval = 0.0f; + // do comparison for every eigenvalue; needed to catch possible NaN-cases. + if (fabs(eigvls.x) > fabs(maxval)) + maxval = eigvls.x; + if (fabs(eigvls.y) > fabs(maxval)) + maxval = eigvls.y; + if (fabs(eigvls.z) > fabs(maxval)) + maxval = eigvls.z; + + float3 retval; + + if (maxval > 0.0f) + { + float3 eigvc = eigenvector(p, maxval); + // check whether the computed eigenvector is in fact a reasonable eigenvector at all. + float3 xform_eigvc = transform(p, eigvc); + float evd = dot(eigvc, eigvc); + float xvd = dot(xform_eigvc, xform_eigvc); + float evx = dot(eigvc, xform_eigvc); + if (evx * evx > evd * xvd * 0.999f) // allow about 1 degree deviation + retval = eigvc; + else + retval = power_method_eigenvector3(p); + } + else + retval = power_method_eigenvector3(p); + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + return retval; +} + + +static float2 get_eigenvector2(const mat2 & p) +{ + + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + float2 eigvls = eigenvalues(p); + float maxval = 0.0f; + // do comparison for every eigenvalue; needed to catch possible NaN-cases. + if (fabs(eigvls.x) > fabs(maxval)) + maxval = eigvls.x; + if (fabs(eigvls.y) > fabs(maxval)) + maxval = eigvls.y; + + float2 retval; + + if (maxval > 0.0f) + { + float2 eigvc = eigenvector(p, maxval); + // check whether the computed eigenvector is in fact a reasonable eigenvector at all. + float2 xform_eigvc = transform(p, eigvc); + float evd = dot(eigvc, eigvc); + float xvd = dot(xform_eigvc, xform_eigvc); + float evx = dot(eigvc, xform_eigvc); + if (evx * evx > evd * xvd * 0.999f) // allow about 1 degree deviation + retval = eigvc; + else + retval = power_method_eigenvector2(p); + } + else + retval = power_method_eigenvector2(p); + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + return retval; +} + + + +/* + For a full block, functions to compute averages and eigenvectors. The averages and eigenvectors are computed separately for each partition. + We have separate versions for blocks with and without alpha, since the processing for blocks with alpha is significantly more expensive. + The eigenvectors it produces are NOT normalized. +*/ + +// compute averages and covariance matrices for 4 components +static void compute_averages_and_covariance_matrices4(const partition_info * pt, + const imageblock * blk, const error_weight_block * ewb, const float4 * color_scalefactors, float4 averages[4], mat4 cov_matrices[4]) +{ + int i; + int partition_count = pt->partition_count; + + int partition; + + for (partition = 0; partition < partition_count; partition++) + { + float r_sum = 0.0f; + float g_sum = 0.0f; + float b_sum = 0.0f; + float a_sum = 0.0f; + float rr_sum = 0.0f; + float gg_sum = 0.0f; + float bb_sum = 0.0f; + float aa_sum = 0.0f; + float rg_sum = 0.0f; + float rb_sum = 0.0f; + float ra_sum = 0.0f; + float gb_sum = 0.0f; + float ga_sum = 0.0f; + float ba_sum = 0.0f; + float partition_weight = 0.0f; + const uint8_t *indexes = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + for (i = 0; i < texelcount; i++) + { + int idx = indexes[i]; + float weight = ewb->texel_weight[idx]; + float r = blk->work_data[4 * idx]; + float g = blk->work_data[4 * idx + 1]; + float b = blk->work_data[4 * idx + 2]; + float a = blk->work_data[4 * idx + 3]; + partition_weight += weight; + r_sum += r * weight; + rr_sum += r * (r * weight); + rg_sum += g * (r * weight); + rb_sum += b * (r * weight); + ra_sum += a * (r * weight); + g_sum += g * weight; + gg_sum += g * (g * weight); + gb_sum += b * (g * weight); + ga_sum += a * (g * weight); + b_sum += b * weight; + bb_sum += b * (b * weight); + ba_sum += a * (b * weight); + a_sum += a * weight; + aa_sum += a * (a * weight); + } + + + float rpt = 1.0f / MAX(partition_weight, 1e-7f); + float rs = r_sum; + float gs = g_sum; + float bs = b_sum; + float as = a_sum; + + float4 csf = color_scalefactors[partition]; + + averages[partition] = float4(rs, gs, bs, as) * csf * rpt; + + float rsc = csf.x; + float gsc = csf.y; + float bsc = csf.z; + float asc = csf.w; + + rs *= rsc; + gs *= gsc; + bs *= bsc; + as *= asc; + + float rrs = rr_sum * rsc * rsc; + float rgs = rg_sum * rsc * gsc; + float rbs = rb_sum * rsc * bsc; + float ras = ra_sum * rsc * asc; + float ggs = gg_sum * gsc * gsc; + float gbs = gb_sum * gsc * bsc; + float gas = ga_sum * gsc * asc; + float bbs = bb_sum * bsc * bsc; + float bas = ba_sum * bsc * asc; + float aas = aa_sum * asc * asc; + + cov_matrices[partition].v[0] = float4(rrs - rs * rs * rpt, rgs - rs * gs * rpt, rbs - rs * bs * rpt, ras - rs * as * rpt); + cov_matrices[partition].v[1] = float4(rgs - rs * gs * rpt, ggs - gs * gs * rpt, gbs - gs * bs * rpt, gas - gs * as * rpt); + cov_matrices[partition].v[2] = float4(rbs - rs * bs * rpt, gbs - gs * bs * rpt, bbs - bs * bs * rpt, bas - bs * as * rpt); + cov_matrices[partition].v[3] = float4(ras - rs * as * rpt, gas - gs * as * rpt, bas - bs * as * rpt, aas - as * as * rpt); + } + +} + + + +// compute averages and covariance matrices for 3 selected components +static void compute_averages_and_covariance_matrices3(const partition_info * pt, + const imageblock * blk, + int component1, + int component2, int component3, const error_weight_block * ewb, const float3 * color_scalefactors, float3 averages[4], mat3 cov_matrices[4]) +{ + int i; + int partition_count = pt->partition_count; + + const float *texel_weights; + if (component1 == 1 && component2 == 2 && component3 == 3) + texel_weights = ewb->texel_weight_gba; + else if (component1 == 0 && component2 == 2 && component3 == 3) + texel_weights = ewb->texel_weight_rba; + else if (component1 == 0 && component2 == 1 && component3 == 3) + texel_weights = ewb->texel_weight_rga; + else if (component1 == 0 && component2 == 1 && component3 == 2) + texel_weights = ewb->texel_weight_rgb; + else + { + texel_weights = ewb->texel_weight_gba; + ASTC_CODEC_INTERNAL_ERROR; + } + + + int partition; + for (partition = 0; partition < partition_count; partition++) + { + float r_sum = 0.0f; + float g_sum = 0.0f; + float b_sum = 0.0f; + float rr_sum = 0.0f; + float gg_sum = 0.0f; + float bb_sum = 0.0f; + float rg_sum = 0.0f; + float rb_sum = 0.0f; + float gb_sum = 0.0f; + float partition_weight = 0.0f; + const uint8_t *indexes = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + for (i = 0; i < texelcount; i++) + { + int idx = indexes[i]; + float weight = texel_weights[idx]; + float r = blk->work_data[4 * idx + component1]; + float g = blk->work_data[4 * idx + component2]; + float b = blk->work_data[4 * idx + component3]; + partition_weight += weight; + r_sum += r * weight; + rr_sum += r * (r * weight); + rg_sum += g * (r * weight); + rb_sum += b * (r * weight); + g_sum += g * weight; + gg_sum += g * (g * weight); + gb_sum += b * (g * weight); + b_sum += b * weight; + bb_sum += b * (b * weight); + } + + float rpt = 1.0f / MAX(partition_weight, 1e-7f); + float rs = r_sum; + float gs = g_sum; + float bs = b_sum; + + float3 csf = color_scalefactors[partition]; + + averages[partition] = float3(rs, gs, bs) * csf * rpt; + + float rsc = csf.x; + float gsc = csf.y; + float bsc = csf.z; + + rs *= rsc; + gs *= gsc; + bs *= bsc; + + float rrs = rr_sum * rsc * rsc; + float rgs = rg_sum * rsc * gsc; + float rbs = rb_sum * rsc * bsc; + float ggs = gg_sum * gsc * gsc; + float gbs = gb_sum * gsc * bsc; + float bbs = bb_sum * bsc * bsc; + + cov_matrices[partition].v[0] = float3(rrs - rs * rs * rpt, rgs - rs * gs * rpt, rbs - rs * bs * rpt); + cov_matrices[partition].v[1] = float3(rgs - rs * gs * rpt, ggs - gs * gs * rpt, gbs - gs * bs * rpt); + cov_matrices[partition].v[2] = float3(rbs - rs * bs * rpt, gbs - gs * bs * rpt, bbs - bs * bs * rpt); + } +} + + + +// compute averages and covariance matrices for 2 selected components +static void compute_averages_and_covariance_matrices2(const partition_info * pt, + const imageblock * blk, + int component1, int component2, const error_weight_block * ewb, const float2 * scalefactors, float2 averages[4], mat2 cov_matrices[4]) +{ + int i; + int partition_count = pt->partition_count; + + const float *texel_weights; + if (component1 == 0 && component2 == 1) + texel_weights = ewb->texel_weight_rg; + else if (component1 == 0 && component2 == 2) + texel_weights = ewb->texel_weight_rb; + else if (component1 == 1 && component2 == 2) + texel_weights = ewb->texel_weight_gb; + else + { + texel_weights = ewb->texel_weight_rg; + // unsupported set of color components. + ASTC_CODEC_INTERNAL_ERROR; + exit(1); + } + + int partition; + for (partition = 0; partition < partition_count; partition++) + { + float c1_sum = 0.0f; + float c2_sum = 0.0f; + float c1c1_sum = 0.0f; + float c2c2_sum = 0.0f; + float c1c2_sum = 0.0f; + float partition_weight = 0.0f; + const uint8_t *indexes = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + for (i = 0; i < texelcount; i++) + { + int idx = indexes[i]; + float weight = texel_weights[idx]; + float c1 = blk->work_data[4 * idx + component1]; + float c2 = blk->work_data[4 * idx + component2]; + partition_weight += weight; + c1_sum += c1 * weight; + c1c1_sum += c1 * (c1 * weight); + c1c2_sum += c2 * (c1 * weight); + c2_sum += c2 * weight; + c2c2_sum += c2 * (c2 * weight); + } + + float rpt = 1.0f / MAX(partition_weight, 1e-7f); + float c1s = c1_sum; + float c2s = c2_sum; + + float2 csf = scalefactors[partition]; + + averages[partition] = float2(c1s, c2s) * csf * rpt; + + float c1sc = csf.x; + float c2sc = csf.y; + + c1s *= c1sc; + c2s *= c2sc; + + float c1c1s = c1c1_sum * c1sc * c1sc; + float c1c2s = c1c2_sum * c1sc * c2sc; + float c2c2s = c2c2_sum * c2sc * c2sc; + + cov_matrices[partition].v[0] = float2(c1c1s - c1s * c1s * rpt, c1c2s - c1s * c2s * rpt); + cov_matrices[partition].v[1] = float2(c1c2s - c1s * c2s * rpt, c2c2s - c2s * c2s * rpt); + } +} + + + + + + +void compute_averages_and_directions_rgba(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float4 * color_scalefactors, + float4 * averages, float4 * eigenvectors_rgba, float3 * eigenvectors_gba, float3 * eigenvectors_rba, float3 * eigenvectors_rga, float3 * eigenvectors_rgb) +{ + int i; + int partition_count = pt->partition_count; + + mat4 covariance_matrices[4]; + + compute_averages_and_covariance_matrices4(pt, blk, ewb, color_scalefactors, averages, covariance_matrices); + + for (i = 0; i < partition_count; i++) + { + eigenvectors_rgba[i] = get_eigenvector4(covariance_matrices[i]); + mat3 rcmat; // reduced covariance matrix + rcmat.v[0] = covariance_matrices[i].v[1].yzw; + rcmat.v[1] = covariance_matrices[i].v[2].yzw; + rcmat.v[2] = covariance_matrices[i].v[3].yzw; + eigenvectors_gba[i] = get_eigenvector3(rcmat); + rcmat.v[0] = covariance_matrices[i].v[0].xzw; + rcmat.v[1] = covariance_matrices[i].v[2].xzw; + rcmat.v[2] = covariance_matrices[i].v[3].xzw; + eigenvectors_rba[i] = get_eigenvector3(rcmat); + rcmat.v[0] = covariance_matrices[i].v[0].xyw; + rcmat.v[1] = covariance_matrices[i].v[1].xyw; + rcmat.v[2] = covariance_matrices[i].v[3].xyw; + eigenvectors_rga[i] = get_eigenvector3(rcmat); + rcmat.v[0] = covariance_matrices[i].v[0].xyz; + rcmat.v[1] = covariance_matrices[i].v[1].xyz; + rcmat.v[2] = covariance_matrices[i].v[2].xyz; + eigenvectors_rgb[i] = get_eigenvector3(rcmat); + } +} + + + + + +void compute_averages_and_directions_rgb(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float4 * color_scalefactors, float3 * averages, float3 * eigenvectors_rgb, float2 * eigenvectors_rg, float2 * eigenvectors_rb, float2 * eigenvectors_gb) +{ + int i; + int partition_count = pt->partition_count; + + + mat3 covariance_matrices[4]; + mat2 rg_matrices[4]; + mat2 rb_matrices[4]; + mat2 gb_matrices[4]; + + float3 scalefactors[4]; + for (i = 0; i < partition_count; i++) + { + float4 scf = color_scalefactors[i]; + scalefactors[i] = scf.xyz; + } + + compute_averages_and_covariance_matrices3(pt, blk, 0, 1, 2, ewb, scalefactors, averages, covariance_matrices); + + for (i = 0; i < partition_count; i++) + { + rg_matrices[i].v[0] = covariance_matrices[i].v[0].xy; + rg_matrices[i].v[1] = covariance_matrices[i].v[1].xy; + rb_matrices[i].v[0] = covariance_matrices[i].v[0].xz; + rb_matrices[i].v[1] = covariance_matrices[i].v[2].xz; + gb_matrices[i].v[0] = covariance_matrices[i].v[1].yz; + gb_matrices[i].v[1] = covariance_matrices[i].v[2].yz; + + eigenvectors_rgb[i] = get_eigenvector3(covariance_matrices[i]); + eigenvectors_rg[i] = get_eigenvector2(rg_matrices[i]); + eigenvectors_rb[i] = get_eigenvector2(rb_matrices[i]); + eigenvectors_gb[i] = get_eigenvector2(gb_matrices[i]); + } +} + + +void compute_averages_and_directions_3_components(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float3 * color_scalefactors, int component1, int component2, int component3, float3 * averages, float3 * eigenvectors) +{ + int i; + int partition_count = pt->partition_count; + + mat3 covariance_matrices[4]; + + compute_averages_and_covariance_matrices3(pt, blk, component1, component2, component3, ewb, color_scalefactors, averages, covariance_matrices); + + for (i = 0; i < partition_count; i++) + eigenvectors[i] = get_eigenvector3(covariance_matrices[i]); +} + + +void compute_averages_and_directions_2_components(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, const float2 * color_scalefactors, int component1, int component2, float2 * averages, float2 * eigenvectors) +{ + int i; + int partition_count = pt->partition_count; + + mat2 covariance_matrices[4]; + + compute_averages_and_covariance_matrices2(pt, blk, component1, component2, ewb, color_scalefactors, averages, covariance_matrices); + + for (i = 0; i < partition_count; i++) + eigenvectors[i] = get_eigenvector2(covariance_matrices[i]); +} + + + + +#define XPASTE(x,y) x##y +#define PASTE(x,y) XPASTE(x,y) + + +#define TWO_COMPONENT_ERROR_FUNC( funcname, c0_idx, c1_idx, c01_name, c01_rname ) \ +float funcname( \ + const partition_info *pt, \ + const imageblock *blk, \ + const error_weight_block *ewb, \ + const processed_line2 *plines, \ + float *length_of_lines \ + ) \ + { \ + int i; \ + float errorsum = 0.0f; \ + int partition; \ + for(partition=0; partitionpartition_count; partition++) \ + { \ + const uint8_t *indexes = pt->texels_of_partition[ partition ]; \ + int texelcount = pt->texels_per_partition[ partition ]; \ + float lowparam = 1e10f; \ + float highparam = -1e10f; \ + processed_line2 l = plines[partition]; \ + if( ewb->contains_zeroweight_texels ) \ + { \ + for(i=0;i PASTE(texel_weight_ , c01_rname) [i]; \ + if( texel_weight > 1e-20f ) \ + { \ + float2 point = float2(blk->work_data[4*idx + c0_idx], blk->work_data[4*idx + c1_idx] ); \ + float param = dot( point, l.bs ); \ + float2 rp1 = l.amod + param*l.bis; \ + float2 dist = rp1 - point; \ + float4 ews = ewb->error_weights[idx]; \ + errorsum += dot( ews. c01_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + } \ + else \ + { \ + for(i=0;iwork_data[4*idx + c0_idx], blk->work_data[4*idx + c1_idx] ); \ + float param = dot( point, l.bs ); \ + float2 rp1 = l.amod + param*l.bis; \ + float2 dist = rp1 - point; \ + float4 ews = ewb->error_weights[idx]; \ + errorsum += dot( ews. c01_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + float linelen = highparam - lowparam; \ + if( !(linelen > 1e-7f) ) \ + linelen = 1e-7f; \ + length_of_lines[partition] = linelen; \ + } \ + return errorsum; \ + } + +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_rg, 0, 1, xy, rg) +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_rb, 0, 2, xz, rb) +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_gb, 1, 2, yz, gb) +TWO_COMPONENT_ERROR_FUNC(compute_error_squared_ra, 0, 3, zw, ra) + + +// function to compute the error across a tile when using a particular set of +// lines for a particular partitioning. Also compute the length of each +// color-space line in each partitioning. + +#define THREE_COMPONENT_ERROR_FUNC( funcname, c0_idx, c1_idx, c2_idx, c012_name, c012_rname ) \ +float funcname( \ + const partition_info *pt, \ + const imageblock *blk, \ + const error_weight_block *ewb, \ + const processed_line3 *plines, \ + float *length_of_lines \ + ) \ + { \ + int i; \ + float errorsum = 0.0f; \ + int partition; \ + for(partition=0; partitionpartition_count; partition++) \ + { \ + const uint8_t *indexes = pt->texels_of_partition[ partition ]; \ + int texelcount = pt->texels_per_partition[ partition ]; \ + float lowparam = 1e10f; \ + float highparam = -1e10f; \ + processed_line3 l = plines[partition]; \ + if( ewb->contains_zeroweight_texels ) \ + { \ + for(i=0;i PASTE(texel_weight_ , c012_rname) [i]; \ + if( texel_weight > 1e-20f ) \ + { \ + float3 point = float3(blk->work_data[4*idx + c0_idx], blk->work_data[4*idx + c1_idx], blk->work_data[4*idx + c2_idx] ); \ + float param = dot( point, l.bs ); \ + float3 rp1 = l.amod + param*l.bis; \ + float3 dist = rp1 - point; \ + float4 ews = ewb->error_weights[idx]; \ + errorsum += dot( ews. c012_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + } \ + else \ + { \ + for(i=0;iwork_data[4*idx + c0_idx], blk->work_data[4*idx + c1_idx], blk->work_data[4*idx + c2_idx] ); \ + float param = dot( point, l.bs ); \ + float3 rp1 = l.amod + param*l.bis; \ + float3 dist = rp1 - point; \ + float4 ews = ewb->error_weights[idx]; \ + errorsum += dot( ews. c012_name, dist*dist ); \ + if( param < lowparam ) lowparam = param; \ + if( param > highparam ) highparam = param; \ + } \ + } \ + float linelen = highparam - lowparam; \ + if( !(linelen > 1e-7f) ) \ + linelen = 1e-7f; \ + length_of_lines[partition] = linelen; \ + } \ + return errorsum; \ + } + +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_gba, 1, 2, 3, yzw, gba) +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_rba, 0, 2, 3, xzw, rba) +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_rga, 0, 1, 3, xyw, rga) +THREE_COMPONENT_ERROR_FUNC(compute_error_squared_rgb, 0, 1, 2, xyz, rgb) + +float compute_error_squared_rgba(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line4 * plines, float *length_of_lines) +{ + int i; + + float errorsum = 0.0f; + int partition; + for (partition = 0; partition < pt->partition_count; partition++) + { + const uint8_t *indexes = pt->texels_of_partition[partition]; + int texelcount = pt->texels_per_partition[partition]; + float lowparam = 1e10; + float highparam = -1e10; + + processed_line4 l = plines[partition]; + + if (ewb->contains_zeroweight_texels) + { + for (i = 0; i < texelcount; i++) + { + int idx = indexes[i]; + if (ewb->texel_weight[idx] > 1e-20) + { + float4 point = float4(blk->work_data[4 * idx], blk->work_data[4 * idx + 1], blk->work_data[4 * idx + 2], blk->work_data[4 * idx + 3]); + float param = dot(point, l.bs); + float4 rp1 = l.amod + param * l.bis; + float4 dist = rp1 - point; + float4 ews = ewb->error_weights[idx]; + errorsum += dot(ews, dist * dist); + if (param < lowparam) + lowparam = param; + if (param > highparam) + highparam = param; + } + } + } + else + { + for (i = 0; i < texelcount; i++) + { + int idx = indexes[i]; + float4 point = float4(blk->work_data[4 * idx], blk->work_data[4 * idx + 1], blk->work_data[4 * idx + 2], blk->work_data[4 * idx + 3]); + float param = dot(point, l.bs); + float4 rp1 = l.amod + param * l.bis; + float4 dist = rp1 - point; + float4 ews = ewb->error_weights[idx]; + errorsum += dot(ews, dist * dist); + if (param < lowparam) + lowparam = param; + if (param > highparam) + highparam = param; + } + } + + float linelen = highparam - lowparam; + if (!(linelen > 1e-7f)) + linelen = 1e-7f; + length_of_lines[partition] = linelen; + } + + return errorsum; +} + + + +// function to compute the error across a tile when using a particular line for +// a particular partition. +float compute_error_squared_rgb_single_partition(int partition_to_test, int xdim, int ydim, int zdim, const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * lin // the line for the partition. + ) +{ + int i; + + int texels_per_block = xdim * ydim * zdim; + + float errorsum = 0.0f; + + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + float texel_weight = ewb->texel_weight_rgb[i]; + if (partition != partition_to_test || texel_weight < 1e-20) + continue; + float3 point = float3(blk->work_data[4 * i], blk->work_data[4 * i + 1], blk->work_data[4 * i + 2]); + + float param = dot(point, lin->bs); + float3 rp1 = lin->amod + param * lin->bis; + float3 dist = rp1 - point; + float4 ews = ewb->error_weights[i]; + + errorsum += dot(ews.xyz, dist * dist); + } + return errorsum; +} diff --git a/third_party/astcenc/Source/astc_block_sizes2.cpp b/third_party/astcenc/Source/astc_block_sizes2.cpp new file mode 100644 index 0000000000..8d42d71c35 --- /dev/null +++ b/third_party/astcenc/Source/astc_block_sizes2.cpp @@ -0,0 +1,977 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief For ASTC, generate the block size descriptor and the associated + * decimation tables. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +extern const float percentile_table_4x4[2048]; +extern const float percentile_table_4x5[2048]; +extern const float percentile_table_4x6[2048]; +extern const float percentile_table_4x8[2048]; +extern const float percentile_table_4x10[2048]; +extern const float percentile_table_4x12[2048]; +extern const float percentile_table_5x4[2048]; +extern const float percentile_table_5x5[2048]; +extern const float percentile_table_5x6[2048]; +extern const float percentile_table_5x8[2048]; +extern const float percentile_table_5x10[2048]; +extern const float percentile_table_5x12[2048]; +extern const float percentile_table_6x4[2048]; +extern const float percentile_table_6x5[2048]; +extern const float percentile_table_6x6[2048]; +extern const float percentile_table_6x8[2048]; +extern const float percentile_table_6x10[2048]; +extern const float percentile_table_6x12[2048]; +extern const float percentile_table_8x4[2048]; +extern const float percentile_table_8x5[2048]; +extern const float percentile_table_8x6[2048]; +extern const float percentile_table_8x8[2048]; +extern const float percentile_table_8x10[2048]; +extern const float percentile_table_8x12[2048]; +extern const float percentile_table_10x4[2048]; +extern const float percentile_table_10x5[2048]; +extern const float percentile_table_10x6[2048]; +extern const float percentile_table_10x8[2048]; +extern const float percentile_table_10x10[2048]; +extern const float percentile_table_10x12[2048]; +extern const float percentile_table_12x4[2048]; +extern const float percentile_table_12x5[2048]; +extern const float percentile_table_12x6[2048]; +extern const float percentile_table_12x8[2048]; +extern const float percentile_table_12x10[2048]; +extern const float percentile_table_12x12[2048]; + +const float *get_2d_percentile_table(int blockdim_x, int blockdim_y) +{ + switch (blockdim_x) + { + case 4: + switch (blockdim_y) + { + case 4: + return percentile_table_4x4; + case 5: + return percentile_table_4x5; + case 6: + return percentile_table_4x6; + case 8: + return percentile_table_4x8; + case 10: + return percentile_table_4x10; + case 12: + return percentile_table_4x12; + } + break; + case 5: + switch (blockdim_y) + { + case 4: + return percentile_table_5x4; + case 5: + return percentile_table_5x5; + case 6: + return percentile_table_5x6; + case 8: + return percentile_table_5x8; + case 10: + return percentile_table_5x10; + case 12: + return percentile_table_5x12; + } + break; + + case 6: + switch (blockdim_y) + { + case 4: + return percentile_table_6x4; + case 5: + return percentile_table_6x5; + case 6: + return percentile_table_6x6; + case 8: + return percentile_table_6x8; + case 10: + return percentile_table_6x10; + case 12: + return percentile_table_6x12; + } + break; + + case 8: + switch (blockdim_y) + { + case 4: + return percentile_table_8x4; + case 5: + return percentile_table_8x5; + case 6: + return percentile_table_8x6; + case 8: + return percentile_table_8x8; + case 10: + return percentile_table_8x10; + case 12: + return percentile_table_8x12; + } + break; + + case 10: + switch (blockdim_y) + { + case 4: + return percentile_table_10x4; + case 5: + return percentile_table_10x5; + case 6: + return percentile_table_10x6; + case 8: + return percentile_table_10x8; + case 10: + return percentile_table_10x10; + case 12: + return percentile_table_10x12; + } + break; + + case 12: + switch (blockdim_y) + { + case 4: + return percentile_table_12x4; + case 5: + return percentile_table_12x5; + case 6: + return percentile_table_12x6; + case 8: + return percentile_table_12x8; + case 10: + return percentile_table_12x10; + case 12: + return percentile_table_12x12; + } + break; + default: + break; + } + + return NULL; // should never happen. +} + +// stubbed for the time being. +static const float dummy_percentile_table_3d[2048] = { 0 }; +const float *get_3d_percentile_table(int blockdim_x, int blockdim_y, int blockdim_z) +{ + IGNORE(blockdim_x); + IGNORE(blockdim_y); + IGNORE(blockdim_z); + return dummy_percentile_table_3d; +} + + + +// return 0 on invalid mode, 1 on valid mode. +static int decode_block_mode_2d(int blockmode, int *Nval, int *Mval, int *dual_weight_plane, int *quant_mode) +{ + int base_quant_mode = (blockmode >> 4) & 1; + int H = (blockmode >> 9) & 1; + int D = (blockmode >> 10) & 1; + + int A = (blockmode >> 5) & 0x3; + + int N = 0, M = 0; + + if ((blockmode & 3) != 0) + { + base_quant_mode |= (blockmode & 3) << 1; + int B = (blockmode >> 7) & 3; + switch ((blockmode >> 2) & 3) + { + case 0: + N = B + 4; + M = A + 2; + break; + case 1: + N = B + 8; + M = A + 2; + break; + case 2: + N = A + 2; + M = B + 8; + break; + case 3: + B &= 1; + if (blockmode & 0x100) + { + N = B + 2; + M = A + 2; + } + else + { + N = A + 2; + M = B + 6; + } + break; + } + } + else + { + base_quant_mode |= ((blockmode >> 2) & 3) << 1; + if (((blockmode >> 2) & 3) == 0) + return 0; + int B = (blockmode >> 9) & 3; + switch ((blockmode >> 7) & 3) + { + case 0: + N = 12; + M = A + 2; + break; + case 1: + N = A + 2; + M = 12; + break; + case 2: + N = A + 6; + M = B + 6; + D = 0; + H = 0; + break; + case 3: + switch ((blockmode >> 5) & 3) + { + case 0: + N = 6; + M = 10; + break; + case 1: + N = 10; + M = 6; + break; + case 2: + case 3: + return 0; + } + break; + } + } + + int weight_count = N * M * (D + 1); + int qmode = (base_quant_mode - 2) + 6 * H; + + int weightbits = compute_ise_bitcount(weight_count, (quantization_method) qmode); + if (weight_count > MAX_WEIGHTS_PER_BLOCK || weightbits < MIN_WEIGHT_BITS_PER_BLOCK || weightbits > MAX_WEIGHT_BITS_PER_BLOCK) + return 0; + + *Nval = N; + *Mval = M; + *dual_weight_plane = D; + *quant_mode = qmode; + return 1; +} + + +static int decode_block_mode_3d(int blockmode, int *Nval, int *Mval, int *Qval, int *dual_weight_plane, int *quant_mode) +{ + int base_quant_mode = (blockmode >> 4) & 1; + int H = (blockmode >> 9) & 1; + int D = (blockmode >> 10) & 1; + + int A = (blockmode >> 5) & 0x3; + + int N = 0, M = 0, Q = 0; + + if ((blockmode & 3) != 0) + { + base_quant_mode |= (blockmode & 3) << 1; + int B = (blockmode >> 7) & 3; + int C = (blockmode >> 2) & 0x3; + N = A + 2; + M = B + 2; + Q = C + 2; + } + else + { + base_quant_mode |= ((blockmode >> 2) & 3) << 1; + if (((blockmode >> 2) & 3) == 0) + return 0; + int B = (blockmode >> 9) & 3; + if (((blockmode >> 7) & 3) != 3) + { + D = 0; + H = 0; + } + switch ((blockmode >> 7) & 3) + { + case 0: + N = 6; + M = B + 2; + Q = A + 2; + break; + case 1: + N = A + 2; + M = 6; + Q = B + 2; + break; + case 2: + N = A + 2; + M = B + 2; + Q = 6; + break; + case 3: + N = 2; + M = 2; + Q = 2; + switch ((blockmode >> 5) & 3) + { + case 0: + N = 6; + break; + case 1: + M = 6; + break; + case 2: + Q = 6; + break; + case 3: + return 0; + } + break; + } + } + + int weight_count = N * M * Q * (D + 1); + int qmode = (base_quant_mode - 2) + 6 * H; + + int weightbits = compute_ise_bitcount(weight_count, (quantization_method) qmode); + if (weight_count > MAX_WEIGHTS_PER_BLOCK || weightbits < MIN_WEIGHT_BITS_PER_BLOCK || weightbits > MAX_WEIGHT_BITS_PER_BLOCK) + return 0; + + *Nval = N; + *Mval = M; + *Qval = Q; + *dual_weight_plane = D; + *quant_mode = qmode; + return 1; +} + + + + +static void initialize_decimation_table_2d( + // dimensions of the block + int xdim, int ydim, + // number of grid points in 2d weight grid + int x_weights, int y_weights, decimation_table * dt) +{ + int i, j; + int x, y; + + int texels_per_block = xdim * ydim; + int weights_per_block = x_weights * y_weights; + + int weightcount_of_texel[MAX_TEXELS_PER_BLOCK]; + int grid_weights_of_texel[MAX_TEXELS_PER_BLOCK][4]; + int weights_of_texel[MAX_TEXELS_PER_BLOCK][4]; + + int texelcount_of_weight[MAX_WEIGHTS_PER_BLOCK]; + int texels_of_weight[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; + int texelweights_of_weight[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; + + for (i = 0; i < weights_per_block; i++) + texelcount_of_weight[i] = 0; + for (i = 0; i < texels_per_block; i++) + weightcount_of_texel[i] = 0; + + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int texel = y * xdim + x; + + int x_weight = (((1024 + xdim / 2) / (xdim - 1)) * x * (x_weights - 1) + 32) >> 6; + int y_weight = (((1024 + ydim / 2) / (ydim - 1)) * y * (y_weights - 1) + 32) >> 6; + + int x_weight_frac = x_weight & 0xF; + int y_weight_frac = y_weight & 0xF; + int x_weight_int = x_weight >> 4; + int y_weight_int = y_weight >> 4; + int qweight[4]; + int weight[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. + int prod = x_weight_frac * y_weight_frac; + + 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 (i = 0; i < 4; i++) + if (weight[i] != 0) + { + grid_weights_of_texel[texel][weightcount_of_texel[texel]] = qweight[i]; + weights_of_texel[texel][weightcount_of_texel[texel]] = weight[i]; + weightcount_of_texel[texel]++; + texels_of_weight[qweight[i]][texelcount_of_weight[qweight[i]]] = texel; + texelweights_of_weight[qweight[i]][texelcount_of_weight[qweight[i]]] = weight[i]; + texelcount_of_weight[qweight[i]]++; + } + } + + for (i = 0; i < texels_per_block; i++) + { + dt->texel_num_weights[i] = weightcount_of_texel[i]; + + // ensure that all 4 entries are actually initialized. + // This allows a branch-free implementation of compute_value_of_texel_flt() + for (j = 0; j < 4; j++) + { + dt->texel_weights_int[i][j] = 0; + dt->texel_weights_float[i][j] = 0.0f; + dt->texel_weights[i][j] = 0; + } + + for (j = 0; j < weightcount_of_texel[i]; j++) + { + dt->texel_weights_int[i][j] = weights_of_texel[i][j]; + dt->texel_weights_float[i][j] = static_cast < float >(weights_of_texel[i][j]) * (1.0f / TEXEL_WEIGHT_SUM); + dt->texel_weights[i][j] = grid_weights_of_texel[i][j]; + } + } + + for (i = 0; i < weights_per_block; i++) + { + dt->weight_num_texels[i] = texelcount_of_weight[i]; + + + for (j = 0; j < texelcount_of_weight[i]; j++) + { + dt->weight_texel[i][j] = texels_of_weight[i][j]; + dt->weights_int[i][j] = texelweights_of_weight[i][j]; + dt->weights_flt[i][j] = static_cast < float >(texelweights_of_weight[i][j]); + } + } + + dt->num_texels = texels_per_block; + dt->num_weights = weights_per_block; + + +} + + + + +static void initialize_decimation_table_3d( + // dimensions of the block + int xdim, int ydim, int zdim, + // number of grid points in 3d weight grid + int x_weights, int y_weights, int z_weights, decimation_table * dt) +{ + int i, j; + int x, y, z; + + int texels_per_block = xdim * ydim * zdim; + int weights_per_block = x_weights * y_weights * z_weights; + + int weightcount_of_texel[MAX_TEXELS_PER_BLOCK]; + int grid_weights_of_texel[MAX_TEXELS_PER_BLOCK][4]; + int weights_of_texel[MAX_TEXELS_PER_BLOCK][4]; + + int texelcount_of_weight[MAX_WEIGHTS_PER_BLOCK]; + int texels_of_weight[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; + int texelweights_of_weight[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; + + for (i = 0; i < weights_per_block; i++) + texelcount_of_weight[i] = 0; + for (i = 0; i < texels_per_block; i++) + weightcount_of_texel[i] = 0; + + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int texel = (z * ydim + y) * xdim + x; + + int x_weight = (((1024 + xdim / 2) / (xdim - 1)) * x * (x_weights - 1) + 32) >> 6; + int y_weight = (((1024 + ydim / 2) / (ydim - 1)) * y * (y_weights - 1) + 32) >> 6; + int z_weight = (((1024 + zdim / 2) / (zdim - 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(i=0;i<4;i++) weight[i] <<= 4; */ + + for (i = 0; i < 4; i++) + if (weight[i] != 0) + { + grid_weights_of_texel[texel][weightcount_of_texel[texel]] = qweight[i]; + weights_of_texel[texel][weightcount_of_texel[texel]] = weight[i]; + weightcount_of_texel[texel]++; + texels_of_weight[qweight[i]][texelcount_of_weight[qweight[i]]] = texel; + texelweights_of_weight[qweight[i]][texelcount_of_weight[qweight[i]]] = weight[i]; + texelcount_of_weight[qweight[i]]++; + } + } + + for (i = 0; i < texels_per_block; i++) + { + dt->texel_num_weights[i] = weightcount_of_texel[i]; + + // ensure that all 4 entries are actually initialized. + // This allows a branch-free implementation of compute_value_of_texel_flt() + for (j = 0; j < 4; j++) + { + dt->texel_weights_int[i][j] = 0; + dt->texel_weights_float[i][j] = 0.0f; + dt->texel_weights[i][j] = 0; + } + + for (j = 0; j < weightcount_of_texel[i]; j++) + { + dt->texel_weights_int[i][j] = weights_of_texel[i][j]; + dt->texel_weights_float[i][j] = static_cast < float >(weights_of_texel[i][j]) * (1.0f / TEXEL_WEIGHT_SUM); + dt->texel_weights[i][j] = grid_weights_of_texel[i][j]; + } + } + + for (i = 0; i < weights_per_block; i++) + { + dt->weight_num_texels[i] = texelcount_of_weight[i]; + for (j = 0; j < texelcount_of_weight[i]; j++) + { + dt->weight_texel[i][j] = texels_of_weight[i][j]; + dt->weights_int[i][j] = texelweights_of_weight[i][j]; + dt->weights_flt[i][j] = static_cast < float >(texelweights_of_weight[i][j]); + } + } + + dt->num_texels = texels_per_block; + dt->num_weights = weights_per_block; +} + + + +void construct_block_size_descriptor_2d(int xdim, int ydim, block_size_descriptor * bsd) +{ + int decimation_mode_index[256]; // for each of the 256 entries in the decim_table_array, its index + int decimation_mode_count = 0; + + int i; + int x_weights; + int y_weights; + + for (i = 0; i < 256; i++) + { + decimation_mode_index[i] = -1; + } + + // gather all the infill-modes that can be used with the current block size + for (x_weights = 2; x_weights <= 12; x_weights++) + for (y_weights = 2; y_weights <= 12; y_weights++) + { + if (x_weights * y_weights > MAX_WEIGHTS_PER_BLOCK) + continue; + decimation_table *dt = new decimation_table; + decimation_mode_index[y_weights * 16 + x_weights] = decimation_mode_count; + initialize_decimation_table_2d(xdim, ydim, x_weights, y_weights, dt); + + int weight_count = x_weights * y_weights; + + int maxprec_1plane = -1; + int maxprec_2planes = -1; + for (i = 0; i < 12; i++) + { + int bits_1plane = compute_ise_bitcount(weight_count, (quantization_method) i); + int bits_2planes = compute_ise_bitcount(2 * weight_count, (quantization_method) i); + if (bits_1plane >= MIN_WEIGHT_BITS_PER_BLOCK && bits_1plane <= MAX_WEIGHT_BITS_PER_BLOCK) + maxprec_1plane = i; + if (bits_2planes >= MIN_WEIGHT_BITS_PER_BLOCK && bits_2planes <= MAX_WEIGHT_BITS_PER_BLOCK) + maxprec_2planes = i; + } + + if (2 * x_weights * y_weights > MAX_WEIGHTS_PER_BLOCK) + maxprec_2planes = -1; + + bsd->permit_encode[decimation_mode_count] = (x_weights <= xdim && y_weights <= ydim); + + bsd->decimation_mode_samples[decimation_mode_count] = weight_count; + bsd->decimation_mode_maxprec_1plane[decimation_mode_count] = maxprec_1plane; + bsd->decimation_mode_maxprec_2planes[decimation_mode_count] = maxprec_2planes; + bsd->decimation_tables[decimation_mode_count] = dt; + + decimation_mode_count++; + } + + for (i = 0; i < MAX_DECIMATION_MODES; i++) + { + bsd->decimation_mode_percentile[i] = 1.0f; + } + + for (i = decimation_mode_count; i < MAX_DECIMATION_MODES; i++) + { + bsd->permit_encode[i] = 0; + bsd->decimation_mode_samples[i] = 0; + bsd->decimation_mode_maxprec_1plane[i] = -1; + bsd->decimation_mode_maxprec_2planes[i] = -1; + } + + bsd->decimation_mode_count = decimation_mode_count; + + const float *percentiles = get_2d_percentile_table(xdim, ydim); + + // then construct the list of block formats + for (i = 0; i < 2048; i++) + { + int x_weights, y_weights; + int is_dual_plane; + int quantization_mode; + int fail = 0; + int permit_encode = 1; + + if (decode_block_mode_2d(i, &x_weights, &y_weights, &is_dual_plane, &quantization_mode)) + { + if (x_weights > xdim || y_weights > ydim) + permit_encode = 0; + } + else + { + fail = 1; + permit_encode = 0; + } + + if (fail) + { + bsd->block_modes[i].decimation_mode = -1; + bsd->block_modes[i].quantization_mode = -1; + bsd->block_modes[i].is_dual_plane = -1; + bsd->block_modes[i].permit_encode = 0; + bsd->block_modes[i].permit_decode = 0; + bsd->block_modes[i].percentile = 1.0f; + } + else + { + int decimation_mode = decimation_mode_index[y_weights * 16 + x_weights]; + bsd->block_modes[i].decimation_mode = decimation_mode; + bsd->block_modes[i].quantization_mode = quantization_mode; + bsd->block_modes[i].is_dual_plane = is_dual_plane; + bsd->block_modes[i].permit_encode = permit_encode; + bsd->block_modes[i].permit_decode = permit_encode; // disallow decode of grid size larger than block size. + bsd->block_modes[i].percentile = percentiles[i]; + + if (bsd->decimation_mode_percentile[decimation_mode] > percentiles[i]) + bsd->decimation_mode_percentile[decimation_mode] = percentiles[i]; + } + + } + + if (xdim * ydim <= 64) + { + bsd->texelcount_for_bitmap_partitioning = xdim * ydim; + for (i = 0; i < xdim * ydim; i++) + bsd->texels_for_bitmap_partitioning[i] = i; + } + + else + { + // pick 64 random texels for use with bitmap partitioning. + int arr[MAX_TEXELS_PER_BLOCK]; + for (i = 0; i < xdim * ydim; i++) + arr[i] = 0; + int arr_elements_set = 0; + while (arr_elements_set < 64) + { + int idx = rand() % (xdim * ydim); + if (arr[idx] == 0) + { + arr_elements_set++; + arr[idx] = 1; + } + } + int texel_weights_written = 0; + int idx = 0; + while (texel_weights_written < 64) + { + if (arr[idx]) + bsd->texels_for_bitmap_partitioning[texel_weights_written++] = idx; + idx++; + } + bsd->texelcount_for_bitmap_partitioning = 64; + + } +} + + + +void construct_block_size_descriptor_3d(int xdim, int ydim, int zdim, block_size_descriptor * bsd) +{ + int decimation_mode_index[512]; // for each of the 512 entries in the decim_table_array, its index + int decimation_mode_count = 0; + + int i; + int x_weights; + int y_weights; + int z_weights; + + for (i = 0; i < 512; i++) + { + decimation_mode_index[i] = -1; + } + + // gather all the infill-modes that can be used with the current block size + for (x_weights = 2; x_weights <= 6; x_weights++) + for (y_weights = 2; y_weights <= 6; y_weights++) + for (z_weights = 2; z_weights <= 6; z_weights++) + { + if ((x_weights * y_weights * z_weights) > MAX_WEIGHTS_PER_BLOCK) + continue; + decimation_table *dt = new decimation_table; + decimation_mode_index[z_weights * 64 + y_weights * 8 + x_weights] = decimation_mode_count; + initialize_decimation_table_3d(xdim, ydim, zdim, x_weights, y_weights, z_weights, dt); + + int weight_count = x_weights * y_weights * z_weights; + + int maxprec_1plane = -1; + int maxprec_2planes = -1; + for (i = 0; i < 12; i++) + { + int bits_1plane = compute_ise_bitcount(weight_count, (quantization_method) i); + int bits_2planes = compute_ise_bitcount(2 * weight_count, (quantization_method) i); + if (bits_1plane >= MIN_WEIGHT_BITS_PER_BLOCK && bits_1plane <= MAX_WEIGHT_BITS_PER_BLOCK) + maxprec_1plane = i; + if (bits_2planes >= MIN_WEIGHT_BITS_PER_BLOCK && bits_2planes <= MAX_WEIGHT_BITS_PER_BLOCK) + maxprec_2planes = i; + } + + if ((2 * x_weights * y_weights * z_weights) > MAX_WEIGHTS_PER_BLOCK) + maxprec_2planes = -1; + + bsd->permit_encode[decimation_mode_count] = (x_weights <= xdim && y_weights <= ydim && z_weights <= zdim); + + bsd->decimation_mode_samples[decimation_mode_count] = weight_count; + bsd->decimation_mode_maxprec_1plane[decimation_mode_count] = maxprec_1plane; + bsd->decimation_mode_maxprec_2planes[decimation_mode_count] = maxprec_2planes; + bsd->decimation_tables[decimation_mode_count] = dt; + + decimation_mode_count++; + } + + for (i = 0; i < MAX_DECIMATION_MODES; i++) + { + bsd->decimation_mode_percentile[i] = 1.0f; + } + + for (i = decimation_mode_count; i < MAX_DECIMATION_MODES; i++) + { + bsd->permit_encode[i] = 0; + bsd->decimation_mode_samples[i] = 0; + bsd->decimation_mode_maxprec_1plane[i] = -1; + bsd->decimation_mode_maxprec_2planes[i] = -1; + } + + bsd->decimation_mode_count = decimation_mode_count; + + const float *percentiles = get_3d_percentile_table(xdim, ydim, zdim); + + // then construct the list of block formats + for (i = 0; i < 2048; i++) + { + int x_weights, y_weights, z_weights; + int is_dual_plane; + int quantization_mode; + int fail = 0; + int permit_encode = 1; + + if (decode_block_mode_3d(i, &x_weights, &y_weights, &z_weights, &is_dual_plane, &quantization_mode)) + { + if (x_weights > xdim || y_weights > ydim || z_weights > zdim) + permit_encode = 0; + } + else + { + fail = 1; + permit_encode = 0; + } + if (fail) + { + bsd->block_modes[i].decimation_mode = -1; + bsd->block_modes[i].quantization_mode = -1; + bsd->block_modes[i].is_dual_plane = -1; + bsd->block_modes[i].permit_encode = 0; + bsd->block_modes[i].permit_decode = 0; + bsd->block_modes[i].percentile = 1.0f; + } + else + { + int decimation_mode = decimation_mode_index[z_weights * 64 + y_weights * 8 + x_weights]; + bsd->block_modes[i].decimation_mode = decimation_mode; + bsd->block_modes[i].quantization_mode = quantization_mode; + bsd->block_modes[i].is_dual_plane = is_dual_plane; + bsd->block_modes[i].permit_encode = permit_encode; + bsd->block_modes[i].permit_decode = permit_encode; + bsd->block_modes[i].percentile = percentiles[i]; + + if (bsd->decimation_mode_percentile[decimation_mode] > percentiles[i]) + bsd->decimation_mode_percentile[decimation_mode] = percentiles[i]; + } + + } + + if (xdim * ydim * zdim <= 64) + { + bsd->texelcount_for_bitmap_partitioning = xdim * ydim * zdim; + for (i = 0; i < xdim * ydim * zdim; i++) + bsd->texels_for_bitmap_partitioning[i] = i; + } + + else + { + // pick 64 random texels for use with bitmap partitioning. + int arr[MAX_TEXELS_PER_BLOCK]; + for (i = 0; i < xdim * ydim * zdim; i++) + arr[i] = 0; + int arr_elements_set = 0; + while (arr_elements_set < 64) + { + int idx = rand() % (xdim * ydim * zdim); + if (arr[idx] == 0) + { + arr_elements_set++; + arr[idx] = 1; + } + } + int texel_weights_written = 0; + int idx = 0; + while (texel_weights_written < 64) + { + if (arr[idx]) + bsd->texels_for_bitmap_partitioning[texel_weights_written++] = idx; + idx++; + } + bsd->texelcount_for_bitmap_partitioning = 64; + } +} + + + + +static block_size_descriptor *bsd_pointers[4096]; + +// function to obtain a block size descriptor. If the descriptor does not exist, +// it is created as needed. Should not be called from within multi-threaded code. +const block_size_descriptor *get_block_size_descriptor(int xdim, int ydim, int zdim) +{ + int bsd_index = xdim + (ydim << 4) + (zdim << 8); + if (bsd_pointers[bsd_index] == NULL) + { + block_size_descriptor *bsd = new block_size_descriptor; + if (zdim > 1) + construct_block_size_descriptor_3d(xdim, ydim, zdim, bsd); + else + construct_block_size_descriptor_2d(xdim, ydim, bsd); + + bsd_pointers[bsd_index] = bsd; + } + return bsd_pointers[bsd_index]; +} diff --git a/third_party/astcenc/Source/astc_codec_internals.h b/third_party/astcenc/Source/astc_codec_internals.h new file mode 100644 index 0000000000..a87cc637f6 --- /dev/null +++ b/third_party/astcenc/Source/astc_codec_internals.h @@ -0,0 +1,815 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012, 2018 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Internal function and data declarations for ASTC codec. + */ +/*----------------------------------------------------------------------------*/ + +#ifndef ASTC_CODEC_INTERNALS_INCLUDED + +#define ASTC_CODEC_INTERNALS_INCLUDED + +#include +#include +#include "mathlib.h" + +#ifndef MIN + #define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +#ifndef MAX + #define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +// Macro to silence warnings on ignored parameters. +// The presence of this macro should be a signal to look at refactoring. +#define IGNORE(param) ((void)¶m) + +#define astc_isnan(p) ((p)!=(p)) + +// ASTC parameters +#define MAX_TEXELS_PER_BLOCK 216 +#define MAX_WEIGHTS_PER_BLOCK 64 +#define MIN_WEIGHT_BITS_PER_BLOCK 24 +#define MAX_WEIGHT_BITS_PER_BLOCK 96 +#define PARTITION_BITS 10 +#define PARTITION_COUNT (1 << PARTITION_BITS) + +// the sum of weights for one texel. +#define TEXEL_WEIGHT_SUM 16 +#define MAX_DECIMATION_MODES 87 +#define MAX_WEIGHT_MODES 2048 + +// error reporting for codec internal errors. +#define ASTC_CODEC_INTERNAL_ERROR astc_codec_internal_error(__FILE__, __LINE__) + +void astc_codec_internal_error(const char *filename, int linenumber); + +// uncomment this macro to enable checking for inappropriate NaNs; +// works on Linux only, and slows down encoding significantly. +// #define DEBUG_CAPTURE_NAN + +// the PRINT_DIAGNOSTICS macro enables the -diag command line switch, +// which can be used to look for codec bugs +#define DEBUG_PRINT_DIAGNOSTICS + +#ifdef DEBUG_PRINT_DIAGNOSTICS + extern int print_diagnostics; +#endif + +extern int print_tile_errors; +extern int print_statistics; + +extern int perform_srgb_transform; +extern int rgb_force_use_of_hdr; +extern int alpha_force_use_of_hdr; + +struct processed_line2 +{ + float2 amod; + float2 bs; + float2 bis; +}; +struct processed_line3 +{ + float3 amod; + float3 bs; + float3 bis; +}; +struct processed_line4 +{ + float4 amod; + float4 bs; + float4 bis; +}; + +enum astc_decode_mode +{ + DECODE_LDR_SRGB, + DECODE_LDR, + DECODE_HDR +}; + + +/* + Partition table representation: + For each block size, we have 3 tables, each with 1024 partitionings; + these three tables correspond to 2, 3 and 4 partitions respectively. + For each partitioning, we have: + * a 4-entry table indicating how many texels there are in each of the 4 partitions. + This may be from 0 to a very large value. + * a table indicating the partition index of each of the texels in the block. + Each index may be 0, 1, 2 or 3. + * Each element in the table is an uint8_t indicating partition index (0, 1, 2 or 3) +*/ + +struct partition_info +{ + int partition_count; + uint8_t texels_per_partition[4]; + uint8_t partition_of_texel[MAX_TEXELS_PER_BLOCK]; + uint8_t texels_of_partition[4][MAX_TEXELS_PER_BLOCK]; + + uint64_t coverage_bitmaps[4]; // used for the purposes of k-means partition search. +}; + + + + +/* + In ASTC, we don't necessarily provide a weight for every texel. + As such, for each block size, there are a number of patterns where some texels + have their weights computed as a weighted average of more than 1 weight. + As such, the codec uses a data structure that tells us: for each texel, which + weights it is a combination of for each weight, which texels it contributes to. + The decimation_table is this data structure. +*/ +struct decimation_table +{ + int num_texels; + int num_weights; + uint8_t texel_num_weights[MAX_TEXELS_PER_BLOCK]; // number of indices that go into the calculation for a texel + uint8_t texel_weights_int[MAX_TEXELS_PER_BLOCK][4]; // the weight to assign to each weight + float texel_weights_float[MAX_TEXELS_PER_BLOCK][4]; // the weight to assign to each weight + uint8_t texel_weights[MAX_TEXELS_PER_BLOCK][4]; // the weights that go into a texel calculation + uint8_t weight_num_texels[MAX_WEIGHTS_PER_BLOCK]; // the number of texels that a given weight contributes to + uint8_t weight_texel[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; // the texels that the weight contributes to + uint8_t weights_int[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; // the weights that the weight contributes to a texel. + float weights_flt[MAX_WEIGHTS_PER_BLOCK][MAX_TEXELS_PER_BLOCK]; // the weights that the weight contributes to a texel. +}; + + + + +/* + data structure describing information that pertains to a block size and its associated block modes. +*/ +struct block_mode +{ + int8_t decimation_mode; + int8_t quantization_mode; + int8_t is_dual_plane; + int8_t permit_encode; + int8_t permit_decode; + float percentile; +}; + + +struct block_size_descriptor +{ + int decimation_mode_count; + int decimation_mode_samples[MAX_DECIMATION_MODES]; + int decimation_mode_maxprec_1plane[MAX_DECIMATION_MODES]; + int decimation_mode_maxprec_2planes[MAX_DECIMATION_MODES]; + float decimation_mode_percentile[MAX_DECIMATION_MODES]; + int permit_encode[MAX_DECIMATION_MODES]; + const decimation_table *decimation_tables[MAX_DECIMATION_MODES + 1]; + block_mode block_modes[MAX_WEIGHT_MODES]; + + // for the k-means bed bitmap partitioning algorithm, we don't + // want to consider more than 64 texels; this array specifies + // which 64 texels (if that many) to consider. + int texelcount_for_bitmap_partitioning; + int texels_for_bitmap_partitioning[64]; +}; + +// data structure representing one block of an image. +// it is expanded to float prior to processing to save some computation time +// on conversions to/from uint8_t (this also allows us to handle HDR textures easily) +struct imageblock +{ + float orig_data[MAX_TEXELS_PER_BLOCK * 4]; // original input data + float work_data[MAX_TEXELS_PER_BLOCK * 4]; // the data that we will compress, either linear or LNS (0..65535 in both cases) + float deriv_data[MAX_TEXELS_PER_BLOCK * 4]; // derivative of the conversion function used, used to modify error weighting + + uint8_t rgb_lns[MAX_TEXELS_PER_BLOCK]; // 1 if RGB data are being treated as LNS + uint8_t alpha_lns[MAX_TEXELS_PER_BLOCK]; // 1 if Alpha data are being treated as LNS + uint8_t nan_texel[MAX_TEXELS_PER_BLOCK]; // 1 if the texel is a NaN-texel. + + float red_min, red_max; + float green_min, green_max; + float blue_min, blue_max; + float alpha_min, alpha_max; + int grayscale; // 1 if R=G=B for every pixel, 0 otherwise + + int xpos, ypos, zpos; +}; + + +struct error_weighting_params +{ + float rgb_power; + float rgb_base_weight; + float rgb_mean_weight; + float rgb_stdev_weight; + float alpha_power; + float alpha_base_weight; + float alpha_mean_weight; + float alpha_stdev_weight; + float rgb_mean_and_stdev_mixing; + int mean_stdev_radius; + int enable_rgb_scale_with_alpha; + int alpha_radius; + int ra_normal_angular_scale; + float block_artifact_suppression; + float rgba_weights[4]; + + float block_artifact_suppression_expanded[MAX_TEXELS_PER_BLOCK]; + + // parameters that deal with heuristic codec speedups + int partition_search_limit; + float block_mode_cutoff; + float texel_avg_error_limit; + float partition_1_to_2_limit; + float lowest_correlation_cutoff; + int max_refinement_iters; +}; + + + + +void update_imageblock_flags(imageblock * pb, int xdim, int ydim, int zdim); + + +void imageblock_initialize_orig_from_work(imageblock * pb, int pixelcount); + + +void imageblock_initialize_work_from_orig(imageblock * pb, int pixelcount); + + + +/* + Data structure representing error weighting for one block of an image. this is used as + a multiplier for the error weight to apply to each color component when computing PSNR. + + This weighting has several uses: it's usable for RA, GA, BA, A weighting, which is useful + for alpha-textures it's usable for HDR textures, where weighting should be approximately inverse to + luminance it's usable for perceptual weighting, where we assign higher weight to low-variability + regions than to high-variability regions. it's usable for suppressing off-edge block content in + case the texture doesn't actually extend to the edge of the block. + + For the default case (everything is evenly weighted), every weight is 1. For the RA,GA,BA,A case, + we multiply the R,G,B weights with that of the alpha. + + Putting the same weight in every component should result in the default case. + The following relations should hold: + + texel_weight_rg[i] = (texel_weight_r[i] + texel_weight_g[i]) / 2 + texel_weight_lum[i] = (texel_weight_r[i] + texel_weight_g[i] + texel_weight_b[i]) / 3 + texel_weight[i] = (texel_weight_r[i] + texel_weight_g[i] + texel_weight_b[i] + texel_weight_a[i] / 4 + */ + +struct error_weight_block +{ + float4 error_weights[MAX_TEXELS_PER_BLOCK]; + float texel_weight[MAX_TEXELS_PER_BLOCK]; + float texel_weight_gba[MAX_TEXELS_PER_BLOCK]; + float texel_weight_rba[MAX_TEXELS_PER_BLOCK]; + float texel_weight_rga[MAX_TEXELS_PER_BLOCK]; + float texel_weight_rgb[MAX_TEXELS_PER_BLOCK]; + + float texel_weight_rg[MAX_TEXELS_PER_BLOCK]; + float texel_weight_rb[MAX_TEXELS_PER_BLOCK]; + float texel_weight_gb[MAX_TEXELS_PER_BLOCK]; + float texel_weight_ra[MAX_TEXELS_PER_BLOCK]; + + float texel_weight_r[MAX_TEXELS_PER_BLOCK]; + float texel_weight_g[MAX_TEXELS_PER_BLOCK]; + float texel_weight_b[MAX_TEXELS_PER_BLOCK]; + float texel_weight_a[MAX_TEXELS_PER_BLOCK]; + + int contains_zeroweight_texels; +}; + + + +struct error_weight_block_orig +{ + float4 error_weights[MAX_TEXELS_PER_BLOCK]; +}; + + +// enumeration of all the quantization methods we support under this format. +enum quantization_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 +}; + + +/* + In ASTC, we support relatively many combinations of weight precisions and weight transfer functions. + As such, for each combination we support, we have a hardwired data structure. + + This structure provides the following information: A table, used to estimate the closest quantized + weight for a given floating-point weight. For each quantized weight, the corresponding unquantized + and floating-point values. For each quantized weight, a previous-value and a next-value. +*/ + +struct quantization_and_transfer_table +{ + quantization_method method; + uint8_t unquantized_value[32]; // 0..64 + float unquantized_value_flt[32]; // 0..1 + uint8_t prev_quantized_value[32]; + uint8_t next_quantized_value[32]; + uint8_t closest_quantized_weight[1025]; +}; + +extern const quantization_and_transfer_table quant_and_xfer_tables[12]; + + + +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, +}; + + + +struct symbolic_compressed_block +{ + int error_block; // 1 marks error block, 0 marks non-error-block. + int block_mode; // 0 to 2047. Negative value marks constant-color block (-1: FP16, -2:UINT16) + int partition_count; // 1 to 4; Zero marks a constant-color block. + int partition_index; // 0 to 1023 + int color_formats[4]; // color format for each endpoint color pair. + int color_formats_matched; // color format for all endpoint pairs are matched. + int color_values[4][12]; // quantized endpoint color pairs. + int color_quantization_level; + uint8_t plane1_weights[MAX_WEIGHTS_PER_BLOCK]; // quantized and decimated weights + uint8_t plane2_weights[MAX_WEIGHTS_PER_BLOCK]; + int plane2_color_component; // color component for the secondary plane of weights + int constant_color[4]; // constant-color, as FP16 or UINT16. Used for constant-color blocks only. +}; + + +struct physical_compressed_block +{ + uint8_t data[16]; +}; + + + + +const block_size_descriptor *get_block_size_descriptor(int xdim, int ydim, int zdim); + + +// *********************************************************** +// functions and data pertaining to quantization and encoding +// ********************************************************** +extern const uint8_t color_quantization_tables[21][256]; +extern const uint8_t color_unquantization_tables[21][256]; + +void encode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset); + +void decode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset); + +int compute_ise_bitcount(int items, quantization_method quant); + +void build_quantization_mode_table(void); +extern int quantization_mode_table[17][128]; + + +// ********************************************** +// functions and data pertaining to partitioning +// ********************************************** + +// function to get a pointer to a partition table or an array thereof. +const partition_info *get_partition_table(int xdim, int ydim, int zdim, int partition_count); + + + + +// functions to compute color averages and dominant directions +// for each partition in a block + + +void compute_averages_and_directions_rgb(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float4 * color_scalefactors, float3 * averages, float3 * directions_rgb, float2 * directions_rg, float2 * directions_rb, float2 * directions_gb); + + + +void compute_averages_and_directions_rgba(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float4 * color_scalefactors, + float4 * averages, float4 * directions_rgba, float3 * directions_gba, float3 * directions_rba, float3 * directions_rga, float3 * directions_rgb); + + +void compute_averages_and_directions_3_components(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, + const float3 * color_scalefactors, int component1, int component2, int component3, float3 * averages, float3 * directions); + +void compute_averages_and_directions_2_components(const partition_info * pt, + const imageblock * blk, + const error_weight_block * ewb, const float2 * color_scalefactors, int component1, int component2, float2 * averages, float2 * directions); + +// functions to compute error value across a tile given a partitioning +// (with the assumption that each partitioning has colors lying on a line where +// they are represented with infinite precision. Also return the length of the line +// segments that the partition's colors are actually projected onto. +float compute_error_squared_gba(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines, + // output: computed length of the partitioning's line. This is not part of the + // error introduced by partitioning itself, but us used to estimate the error introduced by quantization + float *length_of_lines); + +float compute_error_squared_rba(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines, + // output: computed length of the partitioning's line. This is not part of the + // error introduced by partitioning itself, but us used to estimate the error introduced by quantization + float *length_of_lines); + +float compute_error_squared_rga(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines, + // output: computed length of the partitioning's line. This is not part of the + // error introduced by partitioning itself, but us used to estimate the error introduced by quantization + float *length_of_lines); + +float compute_error_squared_rgb(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * plines, + // output: computed length of the partitioning's line. This is not part of the + // error introduced by partitioning itself, but us used to estimate the error introduced by quantization + float *length_of_lines); + + +float compute_error_squared_rgba(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line4 * lines, // one line for each of the partitions. The lines are assumed to be normalized. + float *length_of_lines); + +float compute_error_squared_rg(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines); + +float compute_error_squared_rb(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines); + +float compute_error_squared_gb(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines); + +float compute_error_squared_ra(const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line2 * plines, float *length_of_lines); + + +// functions to compute error value across a tile for a particular line function +// for a single partition. +float compute_error_squared_rgb_single_partition(int partition_to_test, int xdim, int ydim, int zdim, const partition_info * pt, // the partition that we use when computing the squared-error. + const imageblock * blk, const error_weight_block * ewb, const processed_line3 * lin // the line for the partition. + ); + + + +// for each partition, compute its color weightings. +void compute_partition_error_color_weightings(int xdim, int ydim, int zdim, const error_weight_block * ewb, const partition_info * pi, float4 error_weightings[4], float4 color_scalefactors[4]); + + + +// function to find the best partitioning for a given block. + +void find_best_partitionings(int partition_search_limit, int xdim, int ydim, int zdim, int partition_count, const imageblock * pb, const error_weight_block * ewb, int candidates_to_return, + // best partitionings to use if the endpoint colors are assumed to be uncorrelated + int *best_partitions_uncorrellated, + // best partitionings to use if the endpoint colors have the same chroma + int *best_partitions_samechroma, + // best partitionings to use if dual plane of weights are present + int *best_partitions_dual_weight_planes); + + +// use k-means clustering to compute a partition ordering for a block. +void kmeans_compute_partition_ordering(int xdim, int ydim, int zdim, int partition_count, const imageblock * blk, int *ordering); + + + + +// ********************************************************* +// functions and data pertaining to images and imageblocks +// ********************************************************* + +struct astc_codec_image +{ + uint8_t ***imagedata8; + uint16_t ***imagedata16; + int xsize; + int ysize; + int zsize; + int padding; +}; + +void destroy_image(astc_codec_image * img); +astc_codec_image *allocate_image(int bitness, int xsize, int ysize, int zsize, int padding); +void initialize_image(astc_codec_image * img); +void fill_image_padding_area(astc_codec_image * img); + + +extern float4 ***input_averages; +extern float4 ***input_variances; +extern float ***input_alpha_averages; + + +// the entries here : 0=red, 1=green, 2=blue, 3=alpha, 4=0.0, 5=1.0 +struct swizzlepattern +{ + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +}; + + + +int determine_image_channels(const astc_codec_image * img); + +// function to compute regional averages and variances for an image +void compute_averages_and_variances(const astc_codec_image * img, float rgb_power_to_use, float alpha_power_to_use, int avg_kernel_radius, int var_kernel_radius, swizzlepattern swz); + + +/* + Functions to load image from file. + If successful, return an astc_codec_image object. + If unsuccessful, returns NULL. + + *result is used to return a result. In case of a successfully loaded image, bits[2:0] + of *result indicate how many components are present, and bit[7] indicate whether + the input image was LDR or HDR (0=LDR, 1=HDR). + + In case of failure, *result is given a negative value. +*/ + + +astc_codec_image *load_ktx_uncompressed_image(const char *filename, int padding, int *result); +astc_codec_image *load_dds_uncompressed_image(const char *filename, int padding, int *result); +astc_codec_image *load_tga_image(const char *tga_filename, int padding, int *result); +astc_codec_image *load_image_with_stb(const char *filename, int padding, int *result); + +astc_codec_image *astc_codec_load_image(const char *filename, int padding, int *result); +int astc_codec_unlink(const char *filename); + +// function to store image to file +// If successful, returns the number of channels in input image +// If unsuccessful, returns a negative number. +int store_ktx_uncompressed_image(const astc_codec_image * img, const char *filename, int bitness); +int store_dds_uncompressed_image(const astc_codec_image * img, const char *filename, int bitness); +int store_tga_image(const astc_codec_image * img, const char *tga_filename, int bitness); + +int astc_codec_store_image(const astc_codec_image * img, const char *filename, int bitness, const char **format_string); + +int get_output_filename_enforced_bitness(const char *filename); + + +// compute a bunch of error metrics +void compute_error_metrics(int input_image_is_hdr, int input_components, const astc_codec_image * img1, const astc_codec_image * img2, int low_fstop, int high_fstop, int psnrmode); + +// fetch an image-block from the input file +void fetch_imageblock(const astc_codec_image * img, imageblock * pb, // picture-block to initialize with image data + // block dimensions + int xdim, int ydim, int zdim, + // position in picture to fetch block from + int xpos, int ypos, int zpos, swizzlepattern swz); + + +// write an image block to the output file buffer. +// the data written are taken from orig_data. +void write_imageblock(astc_codec_image * img, const imageblock * pb, // picture-block to initialize with image data + // block dimensions + int xdim, int ydim, int zdim, + // position in picture to write block to. + int xpos, int ypos, int zpos, swizzlepattern swz); + + +// helper function to check whether a given picture-block has alpha that is not +// just uniformly 1. +int imageblock_uses_alpha(int xdim, int ydim, int zdim, const imageblock * pb); + + +float compute_imageblock_difference(int xdim, int ydim, int zdim, const imageblock * p1, const imageblock * p2, const error_weight_block * ewb); + + + + + +// *********************************************************** +// functions pertaining to computing texel weights for a block +// *********************************************************** + + +struct endpoints +{ + int partition_count; + float4 endpt0[4]; + float4 endpt1[4]; +}; + + +struct endpoints_and_weights +{ + endpoints ep; + float weights[MAX_TEXELS_PER_BLOCK]; + float weight_error_scale[MAX_TEXELS_PER_BLOCK]; +}; + + +void compute_endpoints_and_ideal_weights_1_plane(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, endpoints_and_weights * ei); + +void compute_endpoints_and_ideal_weights_2_planes(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, int separate_component, + endpoints_and_weights * ei1, // for the three components of the primary plane of weights + endpoints_and_weights * ei2 // for the remaining component. + ); + +void compute_ideal_weights_for_decimation_table(const endpoints_and_weights * eai, const decimation_table * it, float *weight_set, float *weights); + +void compute_ideal_quantized_weights_for_decimation_table(const endpoints_and_weights * eai, + const decimation_table * it, + float low_bound, float high_bound, const float *weight_set_in, float *weight_set_out, uint8_t * quantized_weight_set, int quantization_level); + + +float compute_error_of_weight_set(const endpoints_and_weights * eai, const decimation_table * it, const float *weights); + + +float compute_value_of_texel_flt(int texel_to_get, const decimation_table * it, const float *weights); + + +int compute_value_of_texel_int(int texel_to_get, const decimation_table * it, const int *weights); + + +void merge_endpoints(const endpoints * ep1, // contains three of the color components + const endpoints * ep2, // contains the remaining color component + int separate_component, endpoints * res); + +// functions dealing with color endpoints + +// function to pack a pair of color endpoints into a series of integers. +// the format used may or may not match the format specified; +// the return value is the format actually used. +int pack_color_endpoints(astc_decode_mode decode_mode, float4 color0, float4 color1, float4 rgbs_color, float4 rgbo_color, float2 luminances, int format, int *output, int quantization_level); + + +// unpack a pair of color endpoints from a series of integers. +void unpack_color_endpoints(astc_decode_mode decode_mode, int format, int quantization_level, const int *input, int *rgb_hdr, int *alpha_hdr, int *nan_endpoint, ushort4 * output0, ushort4 * output1); + + +struct encoding_choice_errors +{ + float rgb_scale_error; // error of using LDR RGB-scale instead of complete endpoints. + float rgb_luma_error; // error of using HDR RGB-scale instead of complete endpoints. + float luminance_error; // error of using luminance instead of RGB + float alpha_drop_error; // error of discarding alpha + float rgb_drop_error; // error of discarding RGB + int can_offset_encode; + int can_blue_contract; +}; + +// buffers used to store intermediate data in compress_symbolic_block_fixed_partition_*() +struct compress_fixed_partition_buffers +{ + endpoints_and_weights* ei1; + endpoints_and_weights* ei2; + endpoints_and_weights* eix1; + endpoints_and_weights* eix2; + float *decimated_quantized_weights; + float *decimated_weights; + float *flt_quantized_decimated_quantized_weights; + uint8_t *u8_quantized_decimated_quantized_weights; +}; + +struct compress_symbolic_block_buffers +{ + error_weight_block *ewb; + error_weight_block_orig *ewbo; + symbolic_compressed_block *tempblocks; + imageblock *temp; + compress_fixed_partition_buffers *plane1; + compress_fixed_partition_buffers *planes2; +}; + +void compute_encoding_choice_errors(int xdim, int ydim, int zdim, const imageblock * pb, const partition_info * pi, const error_weight_block * ewb, + int separate_component, // component that is separated out in 2-plane mode, -1 in 1-plane mode + encoding_choice_errors * eci); + + + +void determine_optimal_set_of_endpoint_formats_to_use(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, const endpoints * ep, + int separate_component, // separate color component for 2-plane mode; -1 for single-plane mode + // bitcounts and errors computed for the various quantization methods + const int *qwt_bitcounts, const float *qwt_errors, + // output data + int partition_format_specifiers[4][4], int quantized_weight[4], int quantization_level[4], int quantization_level_mod[4]); + + +void recompute_ideal_colors(int xdim, int ydim, int zdim, int weight_quantization_mode, endpoints * ep, // contains the endpoints we wish to update + float4 * rgbs_vectors, // used to return RGBS-vectors for endpoint mode #6 + float4 * rgbo_vectors, // used to return RGBS-vectors for endpoint mode #7 + float2 * lum_vectors, // used to return luminance-vectors. + const uint8_t * weight_set, // the current set of weight values + const uint8_t * plane2_weight_set, // NULL if plane 2 is not actually used. + int plane2_color_component, // color component for 2nd plane of weights; -1 if the 2nd plane of weights is not present + const partition_info * pi, const decimation_table * it, const imageblock * pb, // picture-block containing the actual data. + const error_weight_block * ewb); + + + +void expand_block_artifact_suppression(int xdim, int ydim, int zdim, error_weighting_params * ewp); + +// Function to set error weights for each color component for each texel in a block. +// Returns the sum of all the error values set. +float prepare_error_weight_block(const astc_codec_image * input_image, + // dimensions of error weight block. + int xdim, int ydim, int zdim, const error_weighting_params * ewp, const imageblock * blk, error_weight_block * ewb, error_weight_block_orig * ewbo); + + +// functions pertaining to weight alignment +void prepare_angular_tables(void); + +void compute_angular_endpoints_1plane(float mode_cutoff, + const block_size_descriptor * bsd, + const float *decimated_quantized_weights, const float *decimated_weights, float low_value[MAX_WEIGHT_MODES], float high_value[MAX_WEIGHT_MODES]); + +void compute_angular_endpoints_2planes(float mode_cutoff, + const block_size_descriptor * bsd, + const float *decimated_quantized_weights, + const float *decimated_weights, + float low_value1[MAX_WEIGHT_MODES], float high_value1[MAX_WEIGHT_MODES], float low_value2[MAX_WEIGHT_MODES], float high_value2[MAX_WEIGHT_MODES]); + + + + +/* *********************************** high-level encode and decode functions ************************************ */ + +float compress_symbolic_block(const astc_codec_image * input_image, + astc_decode_mode decode_mode, int xdim, int ydim, int zdim, const error_weighting_params * ewp, const imageblock * blk, symbolic_compressed_block * scb, + compress_symbolic_block_buffers * tmpbuf); + + +float4 lerp_color_flt(const float4 color0, const float4 color1, float weight, // 0..1 + float plane2_weight, // 0..1 + int plane2_color_component // 0..3; -1 if only one plane of weights is present. + ); + + +ushort4 lerp_color_int(astc_decode_mode decode_mode, ushort4 color0, ushort4 color1, int weight, // 0..64 + int plane2_weight, // 0..64 + int plane2_color_component // 0..3; -1 if only one plane of weights is present. + ); + + +void decompress_symbolic_block(astc_decode_mode decode_mode, + // dimensions of block + int xdim, int ydim, int zdim, + // position of block + int xpos, int ypos, int zpos, const symbolic_compressed_block * scb, imageblock * blk); + + +physical_compressed_block symbolic_to_physical(int xdim, int ydim, int zdim, const symbolic_compressed_block * sc); + +void physical_to_symbolic(int xdim, int ydim, int zdim, physical_compressed_block pb, symbolic_compressed_block * res); + + +uint16_t unorm16_to_sf16(uint16_t p); +uint16_t lns_to_sf16(uint16_t p); + + +#endif diff --git a/third_party/astcenc/Source/astc_color_quantize.cpp b/third_party/astcenc/Source/astc_color_quantize.cpp new file mode 100644 index 0000000000..caa2ba8033 --- /dev/null +++ b/third_party/astcenc/Source/astc_color_quantize.cpp @@ -0,0 +1,2096 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Color quantization functions for ASTC. + */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "astc_codec_internals.h" +#include "softfloat.h" +#include + +#ifdef DEBUG_PRINT_DIAGNOSTICS + #include +#endif + +/* + quantize an LDR RGB color. Since this is a fall-back encoding, we cannot actually + fail but must just go on until we can produce a sensible result. + + Due to how this encoding works, color0 cannot be larger than color1; as such, + if color0 is actually larger than color1, then color0 is reduced and color1 is + increased until color0 is no longer larger than color1. +*/ +static inline int cqt_lookup(int quantization_level, int value) +{ + if (value < 0) + value = 0; + else if (value > 255) + value = 255; + return color_quantization_tables[quantization_level][value]; +} + +// clamp an input value to [0,255]; NaN is turned into 0 +static inline float clamp255(float val) +{ + if (val > 255.0f) + val = 255.0f; + else if (val > 0.0f) + { + // deliberately empty + // switching the order of calculation here will fail to handle 0. + } + else + val = 0.0f; + + return val; +} + + + +// clamp an input value to [0,1]; Nan is turned into 0. + +static inline float clamp01(float val) +{ + if (val > 1.0f) + val = 1.0f; + else if (val > 0.0f) + { + // deliberately empty + // switching the order of calculation here will fail to handle 0. + } + else + val = 0.0f; + + return val; +} + + + +void quantize_rgb(float4 color0, // LDR: 0=lowest, 255=highest + float4 color1, int output[6], int quantization_level) +{ + color0.xyz = color0.xyz * (1.0f / 257.0f); + color1.xyz = color1.xyz * (1.0f / 257.0f); + + + float r0 = clamp255(color0.x); + float g0 = clamp255(color0.y); + float b0 = clamp255(color0.z); + + float r1 = clamp255(color1.x); + float g1 = clamp255(color1.y); + float b1 = clamp255(color1.z); + + int ri0, gi0, bi0, ri1, gi1, bi1; + int ri0b, gi0b, bi0b, ri1b, gi1b, bi1b; + float rgb0_addon = 0.5f; + float rgb1_addon = 0.5f; + int iters = 0; + do + { + ri0 = cqt_lookup(quantization_level, (int)floor(r0 + rgb0_addon)); + gi0 = cqt_lookup(quantization_level, (int)floor(g0 + rgb0_addon)); + bi0 = cqt_lookup(quantization_level, (int)floor(b0 + rgb0_addon)); + ri1 = cqt_lookup(quantization_level, (int)floor(r1 + rgb1_addon)); + gi1 = cqt_lookup(quantization_level, (int)floor(g1 + rgb1_addon)); + bi1 = cqt_lookup(quantization_level, (int)floor(b1 + rgb1_addon)); + + ri0b = color_unquantization_tables[quantization_level][ri0]; + gi0b = color_unquantization_tables[quantization_level][gi0]; + bi0b = color_unquantization_tables[quantization_level][bi0]; + ri1b = color_unquantization_tables[quantization_level][ri1]; + gi1b = color_unquantization_tables[quantization_level][gi1]; + bi1b = color_unquantization_tables[quantization_level][bi1]; + + rgb0_addon -= 0.2f; + rgb1_addon += 0.2f; + iters++; + } + while (ri0b + gi0b + bi0b > ri1b + gi1b + bi1b); + + output[0] = ri0; + output[1] = ri1; + output[2] = gi0; + output[3] = gi1; + output[4] = bi0; + output[5] = bi1; +} + + +/* + quantize an RGBA color. */ +void quantize_rgba(float4 color0, float4 color1, int output[8], int quantization_level) +{ + color0.w = color0.w * (1.0f / 257.0f); + color1.w = color1.w * (1.0f / 257.0f); + + float a0 = clamp255(color0.w); + float a1 = clamp255(color1.w); + int ai0 = color_quantization_tables[quantization_level][(int)floor(a0 + 0.5f)]; + int ai1 = color_quantization_tables[quantization_level][(int)floor(a1 + 0.5f)]; + + output[6] = ai0; + output[7] = ai1; + + quantize_rgb(color0, color1, output, quantization_level); +} + + + +/* + attempt to quantize RGB endpoint values with blue-contraction. Returns 1 on failure, 0 on success. */ +int try_quantize_rgb_blue_contract(float4 color0, // assumed to be the smaller color + float4 color1, // assumed to be the larger color + int output[6], int quantization_level) +{ + color0.xyz = color0.xyz * (1.0f / 257.0f); + color1.xyz = color1.xyz * (1.0f / 257.0f); + + float r0 = color0.x; + float g0 = color0.y; + float b0 = color0.z; + + float r1 = color1.x; + float g1 = color1.y; + float b1 = color1.z; + + // inverse blue-contraction. This can produce an overflow; + // just bail out immediately if this is the case. + 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 0; + } + + // quantize the inverse-blue-contracted color + int ri0 = color_quantization_tables[quantization_level][(int)floor(r0 + 0.5f)]; + int gi0 = color_quantization_tables[quantization_level][(int)floor(g0 + 0.5f)]; + int bi0 = color_quantization_tables[quantization_level][(int)floor(b0 + 0.5f)]; + int ri1 = color_quantization_tables[quantization_level][(int)floor(r1 + 0.5f)]; + int gi1 = color_quantization_tables[quantization_level][(int)floor(g1 + 0.5f)]; + int bi1 = color_quantization_tables[quantization_level][(int)floor(b1 + 0.5f)]; + + // then unquantize again + int ru0 = color_unquantization_tables[quantization_level][ri0]; + int gu0 = color_unquantization_tables[quantization_level][gi0]; + int bu0 = color_unquantization_tables[quantization_level][bi0]; + int ru1 = color_unquantization_tables[quantization_level][ri1]; + int gu1 = color_unquantization_tables[quantization_level][gi1]; + int bu1 = color_unquantization_tables[quantization_level][bi1]; + + // if color #1 is not larger than color #0, then blue-contraction is not a valid approach. + // note that blue-contraction and quantization may itself change this order, which is why + // we must only test AFTER blue-contraction. + if (ru1 + gu1 + bu1 <= ru0 + gu0 + bu0) + return 0; + + output[0] = ri1; + output[1] = ri0; + output[2] = gi1; + output[3] = gi0; + output[4] = bi1; + output[5] = bi0; + + return 1; +} + + + + +/* + quantize an RGBA color with blue-contraction */ +int try_quantize_rgba_blue_contract(float4 color0, float4 color1, int output[8], int quantization_level) +{ + color0.w = color0.w * (1.0f / 257.0f); + color1.w = color1.w * (1.0f / 257.0f); + + float a0 = clamp255(color0.w); + float a1 = clamp255(color1.w); + + output[7] = color_quantization_tables[quantization_level][(int)floor(a0 + 0.5f)]; + output[6] = color_quantization_tables[quantization_level][(int)floor(a1 + 0.5f)]; + + return try_quantize_rgb_blue_contract(color0, color1, output, quantization_level); +} + + +// 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 nonnegative, then we encode a regular delta. + + +/* + attempt to quantize an RGB endpoint value with delta-encoding. */ + +int try_quantize_rgb_delta(float4 color0, float4 color1, int output[6], int quantization_level) +{ + color0.xyz = color0.xyz * (1.0f / 257.0f); + color1.xyz = color1.xyz * (1.0f / 257.0f); + + float r0 = clamp255(color0.x); + float g0 = clamp255(color0.y); + float b0 = clamp255(color0.z); + + float r1 = clamp255(color1.x); + float g1 = clamp255(color1.y); + float b1 = clamp255(color1.z); + + // transform r0 to unorm9 + int r0a = (int)floor(r0 + 0.5f); + int g0a = (int)floor(g0 + 0.5f); + int b0a = (int)floor(b0 + 0.5f); + 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 = color_quantization_tables[quantization_level][r0b]; + int g0be = color_quantization_tables[quantization_level][g0b]; + int b0be = color_quantization_tables[quantization_level][b0b]; + + r0b = color_unquantization_tables[quantization_level][r0be]; + g0b = color_unquantization_tables[quantization_level][g0be]; + b0b = color_unquantization_tables[quantization_level][b0be]; + r0b |= r0a & 0x100; // final unquantized-values for endpoint 0. + g0b |= g0a & 0x100; + b0b |= b0a & 0x100; + + // then, get hold of the second value + int r1d = (int)floor(r1 + 0.5f); + int g1d = (int)floor(g1 + 0.5f); + int b1d = (int)floor(b1 + 0.5f); + + 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 0; + + // 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 & 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 = color_quantization_tables[quantization_level][r1d]; + int g1de = color_quantization_tables[quantization_level][g1d]; + int b1de = color_quantization_tables[quantization_level][b1d]; + + int r1du = color_unquantization_tables[quantization_level][r1de]; + int g1du = color_unquantization_tables[quantization_level][g1de]; + int b1du = color_unquantization_tables[quantization_level][b1de]; + + if (((r1d ^ r1du) | (g1d ^ g1du) | (b1d ^ b1du)) & 0xC0) + return 0; + + // check that the sum of the encoded offsets is nonnegative, else encoding fails + r1du &= 0x7f; + g1du &= 0x7f; + b1du &= 0x7f; + if (r1du & 0x40) + r1du -= 0x80; + if (g1du & 0x40) + g1du -= 0x80; + if (b1du & 0x40) + b1du -= 0x80; + if (r1du + g1du + b1du < 0) + return 0; + + // check that the offsets produce legitimate sums as well. + r1du += r0b; + g1du += g0b; + b1du += b0b; + if (r1du < 0 || r1du > 0x1FF || g1du < 0 || g1du > 0x1FF || b1du < 0 || b1du > 0x1FF) + return 0; + + // OK, we've come this far; we can now encode legitimate values. + output[0] = r0be; + output[1] = r1de; + output[2] = g0be; + output[3] = g1de; + output[4] = b0be; + output[5] = b1de; + + return 1; +} + + +int try_quantize_rgb_delta_blue_contract(float4 color0, float4 color1, int output[6], int quantization_level) +{ + color0.xyz = color0.xyz * (1.0f / 257.0f); + color1.xyz = color1.xyz * (1.0f / 257.0f); + + // switch around endpoint colors already at start. + float r0 = color1.x; + float g0 = color1.y; + float b0 = color1.z; + + float r1 = color0.x; + float g1 = color0.y; + float b1 = color0.z; + + // inverse blue-contraction. This step can perform an overflow, in which case + // we will bail out immediately. + 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 0; + + // transform r0 to unorm9 + int r0a = (int)floor(r0 + 0.5f); + int g0a = (int)floor(g0 + 0.5f); + int b0a = (int)floor(b0 + 0.5f); + 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 = color_quantization_tables[quantization_level][r0b]; + int g0be = color_quantization_tables[quantization_level][g0b]; + int b0be = color_quantization_tables[quantization_level][b0b]; + + r0b = color_unquantization_tables[quantization_level][r0be]; + g0b = color_unquantization_tables[quantization_level][g0be]; + b0b = color_unquantization_tables[quantization_level][b0be]; + r0b |= r0a & 0x100; // final unquantized-values for endpoint 0. + g0b |= g0a & 0x100; + b0b |= b0a & 0x100; + + // then, get hold of the second value + int r1d = (int)floor(r1 + 0.5f); + int g1d = (int)floor(g1 + 0.5f); + int b1d = (int)floor(b1 + 0.5f); + + 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 0; + + // 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 & 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 = color_quantization_tables[quantization_level][r1d]; + int g1de = color_quantization_tables[quantization_level][g1d]; + int b1de = color_quantization_tables[quantization_level][b1d]; + + int r1du = color_unquantization_tables[quantization_level][r1de]; + int g1du = color_unquantization_tables[quantization_level][g1de]; + int b1du = color_unquantization_tables[quantization_level][b1de]; + + if (((r1d ^ r1du) | (g1d ^ g1du) | (b1d ^ b1du)) & 0xC0) + return 0; + + // check that the sum of the encoded offsets is negative, else encoding fails + // note that this is inverse of the test for non-blue-contracted RGB. + r1du &= 0x7f; + g1du &= 0x7f; + b1du &= 0x7f; + if (r1du & 0x40) + r1du -= 0x80; + if (g1du & 0x40) + g1du -= 0x80; + if (b1du & 0x40) + b1du -= 0x80; + if (r1du + g1du + b1du >= 0) + return 0; + + // check that the offsets produce legitimate sums as well. + r1du += r0b; + g1du += g0b; + b1du += b0b; + if (r1du < 0 || r1du > 0x1FF || g1du < 0 || g1du > 0x1FF || b1du < 0 || b1du > 0x1FF) + return 0; + + // OK, we've come this far; we can now encode legitimate values. + output[0] = r0be; + output[1] = r1de; + output[2] = g0be; + output[3] = g1de; + output[4] = b0be; + output[5] = b1de; + + return 1; +} + + +int try_quantize_alpha_delta(float4 color0, float4 color1, int output[8], int quantization_level) +{ + color0.w = color0.w * (1.0f / 257.0f); + color1.w = color1.w * (1.0f / 257.0f); + + // the calculation for alpha-delta is exactly the same as for RGB-delta; see + // the RGB-delta function for comments. + float a0 = clamp255(color0.w); + float a1 = clamp255(color1.w); + + int a0a = (int)floor(a0 + 0.5f); + a0a <<= 1; + int a0b = a0a & 0xFF; + int a0be = color_quantization_tables[quantization_level][a0b]; + a0b = color_unquantization_tables[quantization_level][a0be]; + a0b |= a0a & 0x100; + int a1d = (int)floor(a1 + 0.5f); + a1d <<= 1; + a1d -= a0b; + if (a1d > 63 || a1d < -64) + return 0; + a1d &= 0x7F; + a1d |= (a0b & 0x100) >> 1; + int a1de = color_quantization_tables[quantization_level][a1d]; + int a1du = color_unquantization_tables[quantization_level][a1de]; + if ((a1d ^ a1du) & 0xC0) + return 0; + a1du &= 0x7F; + if (a1du & 0x40) + a1du -= 0x80; + a1du += a0b; + if (a1du < 0 || a1du > 0x1FF) + return 0; + output[6] = a0be; + output[7] = a1de; + return 1; +} + + + +int try_quantize_luminance_alpha_delta(float4 color0, float4 color1, int output[8], int quantization_level) +{ + float l0 = clamp255((color0.x + color0.y + color0.z) * ((1.0f / 3.0f) * (1.0f / 257.0f))); + float l1 = clamp255((color1.x + color1.y + color1.z) * ((1.0f / 3.0f) * (1.0f / 257.0f))); + float a0 = clamp255(color0.w * (1.0f / 257.0f)); + float a1 = clamp255(color1.w * (1.0f / 257.0f)); + + int l0a = (int)floor(l0 + 0.5f); + int a0a = (int)floor(a0 + 0.5f); + l0a <<= 1; + a0a <<= 1; + int l0b = l0a & 0xFF; + int a0b = a0a & 0xFF; + int l0be = color_quantization_tables[quantization_level][l0b]; + int a0be = color_quantization_tables[quantization_level][a0b]; + l0b = color_unquantization_tables[quantization_level][l0be]; + a0b = color_unquantization_tables[quantization_level][a0be]; + l0b |= l0a & 0x100; + a0b |= a0a & 0x100; + int l1d = (int)floor(l1 + 0.5f); + int a1d = (int)floor(a1 + 0.5f); + l1d <<= 1; + a1d <<= 1; + l1d -= l0b; + a1d -= a0b; + if (l1d > 63 || l1d < -64) + return 0; + if (a1d > 63 || a1d < -64) + return 0; + l1d &= 0x7F; + a1d &= 0x7F; + l1d |= (l0b & 0x100) >> 1; + a1d |= (a0b & 0x100) >> 1; + + int l1de = color_quantization_tables[quantization_level][l1d]; + int a1de = color_quantization_tables[quantization_level][a1d]; + int l1du = color_unquantization_tables[quantization_level][l1de]; + int a1du = color_unquantization_tables[quantization_level][a1de]; + if ((l1d ^ l1du) & 0xC0) + return 0; + if ((a1d ^ a1du) & 0xC0) + return 0; + l1du &= 0x7F; + a1du &= 0x7F; + if (l1du & 0x40) + l1du -= 0x80; + if (a1du & 0x40) + a1du -= 0x80; + l1du += l0b; + a1du += a0b; + if (l1du < 0 || l1du > 0x1FF) + return 0; + if (a1du < 0 || a1du > 0x1FF) + return 0; + output[0] = l0be; + output[1] = l1de; + output[2] = a0be; + output[3] = a1de; + + return 1; +} + + + + +int try_quantize_rgba_delta(float4 color0, float4 color1, int output[8], int quantization_level) +{ + int alpha_delta_res = try_quantize_alpha_delta(color0, color1, output, quantization_level); + + if (alpha_delta_res == 0) + return 0; + + return try_quantize_rgb_delta(color0, color1, output, quantization_level); +} + + +int try_quantize_rgba_delta_blue_contract(float4 color0, float4 color1, int output[8], int quantization_level) +{ + // notice that for the alpha encoding, we are swapping around color0 and color1; + // this is because blue-contraction involves swapping around the two colors. + int alpha_delta_res = try_quantize_alpha_delta(color1, color0, output, quantization_level); + + if (alpha_delta_res == 0) + return 0; + + return try_quantize_rgb_delta_blue_contract(color0, color1, output, quantization_level); +} + + + +void quantize_rgbs_new(float4 rgbs_color, // W component is a desired-scale to apply, in the range 0..1 + int output[4], int quantization_level) +{ + rgbs_color.xyz = rgbs_color.xyz * (1.0f / 257.0f); + + float r = clamp255(rgbs_color.x); + float g = clamp255(rgbs_color.y); + float b = clamp255(rgbs_color.z); + + int ri = color_quantization_tables[quantization_level][(int)floor(r + 0.5f)]; + int gi = color_quantization_tables[quantization_level][(int)floor(g + 0.5f)]; + int bi = color_quantization_tables[quantization_level][(int)floor(b + 0.5f)]; + + int ru = color_unquantization_tables[quantization_level][ri]; + int gu = color_unquantization_tables[quantization_level][gi]; + int bu = color_unquantization_tables[quantization_level][bi]; + + float oldcolorsum = rgbs_color.x + rgbs_color.y + rgbs_color.z; + float newcolorsum = (float)(ru + gu + bu); + + float scale = clamp01(rgbs_color.w * (oldcolorsum + 1e-10f) / (newcolorsum + 1e-10f)); + + int scale_idx = (int)floor(scale * 256.0f + 0.5f); + + if (scale_idx < 0) + scale_idx = 0; + else if (scale_idx > 255) + scale_idx = 255; + + output[0] = ri; + output[1] = gi; + output[2] = bi; + output[3] = color_quantization_tables[quantization_level][scale_idx]; +} + + + +void quantize_rgbs_alpha_new(float4 color0, float4 color1, float4 rgbs_color, int output[6], int quantization_level) +{ + color0.w = color0.w * (1.0f / 257.0f); + color1.w = color1.w * (1.0f / 257.0f); + + float a0 = clamp255(color0.w); + float a1 = clamp255(color1.w); + + int ai0 = color_quantization_tables[quantization_level][(int)floor(a0 + 0.5f)]; + int ai1 = color_quantization_tables[quantization_level][(int)floor(a1 + 0.5f)]; + + output[4] = ai0; + output[5] = ai1; + + quantize_rgbs_new(rgbs_color, output, quantization_level); +} + + + +void quantize_luminance(float4 color0, float4 color1, int output[2], int quantization_level) +{ + color0.xyz = color0.xyz * (1.0f / 257.0f); + color1.xyz = color1.xyz * (1.0f / 257.0f); + + float lum0 = clamp255((color0.x + color0.y + color0.z) * (1.0f / 3.0f)); + float lum1 = clamp255((color1.x + color1.y + color1.z) * (1.0f / 3.0f)); + + if (lum0 > lum1) + { + float avg = (lum0 + lum1) * 0.5f; + lum0 = avg; + lum1 = avg; + } + + output[0] = color_quantization_tables[quantization_level][(int)floor(lum0 + 0.5f)]; + output[1] = color_quantization_tables[quantization_level][(int)floor(lum1 + 0.5f)]; +} + + + + + + +void quantize_luminance_alpha(float4 color0, float4 color1, int output[4], int quantization_level) +{ + color0 = color0 * (1.0f / 257.0f); + color1 = color1 * (1.0f / 257.0f); + + float lum0 = clamp255((color0.x + color0.y + color0.z) * (1.0f / 3.0f)); + float lum1 = clamp255((color1.x + color1.y + color1.z) * (1.0f / 3.0f)); + float a0 = clamp255(color0.w); + float a1 = clamp255(color1.w); + + // if the endpoints are *really* close, then pull them apart slightly; + // this affords for >8 bits precision for normal maps. + if (quantization_level > 18 && fabs(lum0 - lum1) < 3.0f) + { + if (lum0 < lum1) + { + lum0 -= 0.5f; + lum1 += 0.5f; + } + else + { + lum0 += 0.5f; + lum1 -= 0.5f; + } + lum0 = clamp255(lum0); + lum1 = clamp255(lum1); + } + if (quantization_level > 18 && fabs(a0 - a1) < 3.0f) + { + if (a0 < a1) + { + a0 -= 0.5f; + a1 += 0.5f; + } + else + { + a0 += 0.5f; + a1 -= 0.5f; + } + a0 = clamp255(a0); + a1 = clamp255(a1); + } + + + output[0] = color_quantization_tables[quantization_level][(int)floor(lum0 + 0.5f)]; + output[1] = color_quantization_tables[quantization_level][(int)floor(lum1 + 0.5f)]; + output[2] = color_quantization_tables[quantization_level][(int)floor(a0 + 0.5f)]; + output[3] = color_quantization_tables[quantization_level][(int)floor(a1 + 0.5f)]; +} + + +void quantize0(float4 color0, float4 color1, int output[8], int quantization_level) +{ + IGNORE(color0); + IGNORE(color1); + IGNORE(output); + IGNORE(quantization_level); + + int i; + for (i = 0; i < 8; i++) + output[i] = 0; +} + + +// quantize and unquantize a number, wile making sure to retain the top two bits. +static inline void quantize_and_unquantize_retain_top_two_bits(int quantization_level, int value_to_quantize, // 0 to 255. + int *quantized_value, int *unquantized_value) +{ + + int perform_loop; + int quantval; + int uquantval; + + do + { + quantval = color_quantization_tables[quantization_level][value_to_quantize]; + uquantval = color_unquantization_tables[quantization_level][quantval]; + + // perform looping if the top two bits were modified by quant/unquant + perform_loop = (value_to_quantize & 0xC0) != (uquantval & 0xC0); + + if ((uquantval & 0xC0) > (value_to_quantize & 0xC0)) + { + // quant/unquant rounded UP so that the top two bits changed; + // decrement the input value in hopes that this will avoid rounding up. + value_to_quantize--; + } + else if ((uquantval & 0xC0) < (value_to_quantize & 0xC0)) + { + // quant/unquant rounded DOWN so that the top two bits changed; + // decrement the input value in hopes that this will avoid rounding down. + value_to_quantize--; + } + } + while (perform_loop); + + *quantized_value = quantval; + *unquantized_value = uquantval; +} + + +// quantize and unquantize a number, wile making sure to retain the top four bits. +static inline void quantize_and_unquantize_retain_top_four_bits(int quantization_level, int value_to_quantize, // 0 to 255. + int *quantized_value, int *unquantized_value) +{ + + int perform_loop; + int quantval; + int uquantval; + + do + { + quantval = color_quantization_tables[quantization_level][value_to_quantize]; + uquantval = color_unquantization_tables[quantization_level][quantval]; + + // perform looping if the top two bits were modified by quant/unquant + perform_loop = (value_to_quantize & 0xF0) != (uquantval & 0xF0); + + if ((uquantval & 0xF0) > (value_to_quantize & 0xF0)) + { + // quant/unquant rounded UP so that the top two bits changed; + // decrement the input value in hopes that this will avoid rounding up. + value_to_quantize--; + } + else if ((uquantval & 0xF0) < (value_to_quantize & 0xF0)) + { + // quant/unquant rounded DOWN so that the top two bits changed; + // decrement the input value in hopes that this will avoid rounding down. + value_to_quantize--; + } + } + while (perform_loop); + + *quantized_value = quantval; + *unquantized_value = uquantval; +} + +// quantize and unquantize a number, wile making sure to retain the top two bits. +static inline void quantize_and_unquantize_retain_top_bit(int quantization_level, int value_to_quantize, // 0 to 255. + int *quantized_value, int *unquantized_value) +{ + + int perform_loop; + int quantval; + int uquantval; + + do + { + quantval = color_quantization_tables[quantization_level][value_to_quantize]; + uquantval = color_unquantization_tables[quantization_level][quantval]; + + // perform looping if the top two bits were modified by quant/unquant + perform_loop = (value_to_quantize & 0x80) != (uquantval & 0x80); + + if ((uquantval & 0x80) > (value_to_quantize & 0x80)) + { + // quant/unquant rounded UP so that the top two bits changed; + // decrement the input value in hopes that this will avoid rounding up. + value_to_quantize--; + } + else if ((uquantval & 0x80) < (value_to_quantize & 0x80)) + { + // quant/unquant rounded DOWN so that the top two bits changed; + // decrement the input value in hopes that this will avoid rounding down. + value_to_quantize--; + } + } + while (perform_loop); + + *quantized_value = quantval; + *unquantized_value = uquantval; +} + + + + + +/* + HDR color encoding, take #3 */ + + +void quantize_hdr_rgbo3(float4 color, int output[4], int quantization_level) +{ + color.xyz = color.xyz + color.www; + + if (!(color.x > 0.0f)) + color.x = 0.0f; + else if (color.x > 65535.0f) + color.x = 65535.0f; + + if (!(color.y > 0.0f)) + color.y = 0.0f; + else if (color.y > 65535.0f) + color.y = 65535.0f; + + if (!(color.z > 0.0f)) + color.z = 0.0f; + else if (color.z > 65535.0f) + color.z = 65535.0f; + + if (!(color.w > 0.0f)) + color.w = 0.0f; + else if (color.w > 65535.0f) + color.w = 65535.0f; + + float4 color_bak = color; + int majcomp; + if (color.x > color.y && color.x > color.z) + majcomp = 0; // red is largest component + else if (color.y > color.z) + 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.yxzw; + break; + case 2: + color = color.zyxw; + 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.x; + float g_base = color.x - color.y; + float b_base = color.x - color.z; + float s_base = color.w; + + int mode; + for (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]; + + // first, quantize and unquantize R. + int r_intval = (int)floor(r_base * mode_scale + 0.5f); + + int r_lowbits = r_intval & 0x3f; + + r_lowbits |= (mode_enc & 3) << 6; + + int r_quantval; + int r_uquantval; + quantize_and_unquantize_retain_top_two_bits(quantization_level, r_lowbits, &r_quantval, &r_uquantval); + + r_intval = (r_intval & ~0x3f) | (r_uquantval & 0x3f); + float r_fval = r_intval * mode_rscale; + + + // next, recompute G and B, then quantize and unquantize them. + float g_fval = r_fval - color.y; + float b_fval = r_fval - color.z; + if (g_fval < 0.0f) + g_fval = 0.0f; + else if (g_fval > 65535.0f) + g_fval = 65535.0f; + if (b_fval < 0.0f) + b_fval = 0.0f; + else if (b_fval > 65535.0f) + b_fval = 65535.0f; + + int g_intval = (int)floor(g_fval * mode_scale + 0.5f); + int b_intval = (int)floor(b_fval * mode_scale + 0.5f); + + + 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; + + int g_quantval; + int b_quantval; + int g_uquantval; + int b_uquantval; + + quantize_and_unquantize_retain_top_four_bits(quantization_level, g_lowbits, &g_quantval, &g_uquantval); + + quantize_and_unquantize_retain_top_four_bits(quantization_level, b_lowbits, &b_quantval, &b_uquantval); + + g_intval = (g_intval & ~0x1f) | (g_uquantval & 0x1f); + b_intval = (b_intval & ~0x1f) | (b_uquantval & 0x1f); + + g_fval = g_intval * mode_rscale; + b_fval = b_intval * mode_rscale; + + + // finally, 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.x) + (r_fval - g_fval - color.y) + (r_fval - b_fval - color.z); + + float s_fval = s_base + rgb_errorsum * (1.0f / 3.0f); + if (s_fval < 0.0f) + s_fval = 0.0f; + else if (s_fval > 1e9) + s_fval = 1e9; + + int s_intval = (int)floor(s_fval * mode_scale + 0.5f); + + 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; + + int s_quantval; + int s_uquantval; + + quantize_and_unquantize_retain_top_four_bits(quantization_level, s_lowbits, &s_quantval, &s_uquantval); + + s_intval = (s_intval & ~0x1f) | (s_uquantval & 0x1f); + s_fval = s_intval * mode_rscale; + 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. + int i; + + float vals[4]; + int ivals[4]; + vals[0] = color_bak.x; + vals[1] = color_bak.y; + vals[2] = color_bak.z; + vals[3] = color_bak.w; + + float cvals[3]; + + for (i = 0; i < 3; i++) + { + if (vals[i] < 0.0f) + vals[i] = 0.0f; + else if (vals[i] > 65020.0f) + vals[i] = 65020.0f; + + ivals[i] = (int)floor(vals[i] * (1.0f / 512.0f) + 0.5f); + cvals[i] = 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); + + if (vals[3] < 0.0f) + vals[3] = 0.0f; + else if (vals[3] > 65020.0f) + vals[3] = 65020.0f; + + ivals[3] = (int)floor(vals[3] * (1.0f / 512.0f) + 0.5f); + + 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 (i = 0; i < 4; i++) + { + int dummy; + quantize_and_unquantize_retain_top_four_bits(quantization_level, encvals[i], &(output[i]), &dummy); + } + + return; +} + + + + + + + +void quantize_hdr_rgb3(float4 color0, float4 color1, int output[6], int quantization_level) +{ + if (!(color0.x > 0.0f)) + color0.x = 0.0f; + else if (color0.x > 65535.0f) + color0.x = 65535.0f; + + if (!(color0.y > 0.0f)) + color0.y = 0.0f; + else if (color0.y > 65535.0f) + color0.y = 65535.0f; + + if (!(color0.z > 0.0f)) + color0.z = 0.0f; + else if (color0.z > 65535.0f) + color0.z = 65535.0f; + + if (!(color1.x > 0.0f)) + color1.x = 0.0f; + else if (color1.x > 65535.0f) + color1.x = 65535.0f; + + if (!(color1.y > 0.0f)) + color1.y = 0.0f; + else if (color1.y > 65535.0f) + color1.y = 65535.0f; + + if (!(color1.z > 0.0f)) + color1.z = 0.0f; + else if (color1.z > 65535.0f) + color1.z = 65535.0f; + + float4 color0_bak = color0; + float4 color1_bak = color1; + + int majcomp; + if (color1.x > color1.y && color1.x > color1.z) + majcomp = 0; // red is largest + else if (color1.y > color1.z) + majcomp = 1; // green is largest + else + majcomp = 2; // blue is largest + + // swizzle the components + switch (majcomp) + { + case 1: // red-green swap + color0 = color0.yxzw; + color1 = color1.yxzw; + break; + case 2: // red-blue swap + color0 = color0.zyxw; + color1 = color1.zyxw; + break; + default: + break; + } + + float a_base = color1.x; + if (a_base < 0.0f) + a_base = 0.0f; + else if (a_base > 65535.0f) + a_base = 65535.0f; + + + float b0_base = a_base - color1.y; + float b1_base = a_base - color1.z; + float c_base = a_base - color0.x; + float d0_base = a_base - b0_base - c_base - color0.y; + float d1_base = a_base - b1_base - c_base - color0.z; + + + + // 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. + int mode; + for (mode = 7; mode >= 0; mode--) + { + // for each mode, test if we can in fact accommodate + // the computed b,c,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 || fabs(d0_base) > d_cutoff || fabs(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); + + // first, quantize and unquantize A, with the assumption that its high bits can be handled safely. + int a_intval = (int)floor(a_base * mode_scale + 0.5f); + int a_lowbits = a_intval & 0xFF; + + int a_quantval = color_quantization_tables[quantization_level][a_lowbits]; + int a_uquantval = color_unquantization_tables[quantization_level][a_quantval]; + a_intval = (a_intval & ~0xFF) | a_uquantval; + float a_fval = a_intval * mode_rscale; + + // next, recompute C, then quantize and unquantize it + float c_fval = a_fval - color0.x; + if (c_fval < 0.0f) + c_fval = 0.0f; + else if (c_fval > 65535.0f) + c_fval = 65535.0f; + + int c_intval = (int)floor(c_fval * mode_scale + 0.5f); + + if (c_intval >= c_intcutoff) + { + continue; + } + + int c_lowbits = c_intval & 0x3f; + + c_lowbits |= (mode & 1) << 7; + c_lowbits |= (a_intval & 0x100) >> 2; + + int c_quantval; + int c_uquantval; + quantize_and_unquantize_retain_top_two_bits(quantization_level, c_lowbits, &c_quantval, &c_uquantval); + c_intval = (c_intval & ~0x3F) | (c_uquantval & 0x3F); + c_fval = c_intval * mode_rscale; + + + // next, recompute B0 and B1, then quantize and unquantize them + float b0_fval = a_fval - color1.y; + float b1_fval = a_fval - color1.z; + if (b0_fval < 0.0f) + b0_fval = 0.0f; + else if (b0_fval > 65535.0f) + b0_fval = 65535.0f; + if (b1_fval < 0.0f) + b1_fval = 0.0f; + else if (b1_fval > 65535.0f) + b1_fval = 65535.0f; + + int b0_intval = (int)floor(b0_fval * mode_scale + 0.5f); + int b1_intval = (int)floor(b1_fval * mode_scale + 0.5f); + + 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; + + int b0_quantval; + int b1_quantval; + int b0_uquantval; + int b1_uquantval; + + quantize_and_unquantize_retain_top_two_bits(quantization_level, b0_lowbits, &b0_quantval, &b0_uquantval); + + quantize_and_unquantize_retain_top_two_bits(quantization_level, b1_lowbits, &b1_quantval, &b1_uquantval); + + b0_intval = (b0_intval & ~0x3f) | (b0_uquantval & 0x3f); + b1_intval = (b1_intval & ~0x3f) | (b1_uquantval & 0x3f); + b0_fval = b0_intval * mode_rscale; + b1_fval = b1_intval * mode_rscale; + + + // finally, recompute D0 and D1, then quantize and unquantize them + float d0_fval = a_fval - b0_fval - c_fval - color0.y; + float d1_fval = a_fval - b1_fval - c_fval - color0.z; + + if (d0_fval < -65535.0f) + d0_fval = -65535.0f; + else if (d0_fval > 65535.0f) + d0_fval = 65535.0f; + + if (d1_fval < -65535.0f) + d1_fval = -65535.0f; + else if (d1_fval > 65535.0f) + d1_fval = 65535.0f; + + int d0_intval = (int)floor(d0_fval * mode_scale + 0.5f); + int d1_intval = (int)floor(d1_fval * mode_scale + 0.5f); + + if (abs(d0_intval) >= d_intcutoff || abs(d1_intval) >= d_intcutoff) + continue; + + // d0_intval += mode_dbiases[mode]; + // d1_intval += mode_dbiases[mode]; + + 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; + + int d0_quantval; + int d1_quantval; + int d0_uquantval; + int d1_uquantval; + + quantize_and_unquantize_retain_top_four_bits(quantization_level, d0_lowbits, &d0_quantval, &d0_uquantval); + + quantize_and_unquantize_retain_top_four_bits(quantization_level, d1_lowbits, &d1_quantval, &d1_uquantval); + + output[0] = a_quantval; + output[1] = c_quantval; + output[2] = b0_quantval; + output[3] = b1_quantval; + output[4] = d0_quantval; + output[5] = d1_quantval; + return; + } + + // neither of the modes fit? In this case, 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. + int i; + float vals[6]; + vals[0] = color0_bak.x; + vals[1] = color1_bak.x; + vals[2] = color0_bak.y; + vals[3] = color1_bak.y; + vals[4] = color0_bak.z; + vals[5] = color1_bak.z; + + + for (i = 0; i < 6; i++) + { + if (vals[i] < 0.0f) + vals[i] = 0.0f; + else if (vals[i] > 65020.0f) + vals[i] = 65020.0f; + } + for (i = 0; i < 4; i++) + { + int idx = (int)floor(vals[i] * 1.0f / 256.0f + 0.5f); + output[i] = color_quantization_tables[quantization_level][idx]; + } + for (i = 4; i < 6; i++) + { + int dummy; + int idx = (int)floor(vals[i] * 1.0f / 512.0f + 0.5f) + 128; + quantize_and_unquantize_retain_top_two_bits(quantization_level, idx, &(output[i]), &dummy); + } + + return; +} + + + + + +void quantize_hdr_rgb_ldr_alpha3(float4 color0, float4 color1, int output[8], int quantization_level) +{ + color0.w *= (1.0f / 257.0f); + color1.w *= (1.0f / 257.0f); + + quantize_hdr_rgb3(color0, color1, output, quantization_level); + + float a0 = clamp255(color0.w); + float a1 = clamp255(color1.w); + int ai0 = color_quantization_tables[quantization_level][(int)floor(a0 + 0.5f)]; + int ai1 = color_quantization_tables[quantization_level][(int)floor(a1 + 0.5f)]; + + output[6] = ai0; + output[7] = ai1; +} + + + +void quantize_hdr_luminance_large_range3(float4 color0, float4 color1, int output[2], int quantization_level) +{ + + float lum1 = (color1.x + color1.y + color1.z) * (1.0f / 3.0f); + float lum0 = (color0.x + color0.y + color0.z) * (1.0f / 3.0f); + + if (lum1 < lum0) + { + float avg = (lum0 + lum1) * 0.5f; + lum0 = avg; + lum1 = avg; + } + + int ilum1 = static_cast < int >(floor(lum1 + 0.5f)); + int ilum0 = static_cast < int >(floor(lum0 + 0.5f)); + + // 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; + + if (upper_v0 < 0) + upper_v0 = 0; + else if (upper_v0 > 255) + upper_v0 = 255; + + if (upper_v1 < 0) + upper_v1 = 0; + else if (upper_v1 > 255) + upper_v1 = 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; + + if (lower_v0 < 0) + lower_v0 = 0; + else if (lower_v0 > 255) + lower_v0 = 255; + + if (lower_v1 < 0) + lower_v1 = 0; + else if (lower_v1 > 255) + lower_v1 = 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] = color_quantization_tables[quantization_level][v0]; + output[1] = color_quantization_tables[quantization_level][v1]; +} + + + +int try_quantize_hdr_luminance_small_range3(float4 color0, float4 color1, int output[2], int quantization_level) +{ + float lum1 = (color1.x + color1.y + color1.z) * (1.0f / 3.0f); + float lum0 = (color0.x + color0.y + color0.z) * (1.0f / 3.0f); + + if (lum1 < lum0) + { + float avg = (lum0 + lum1) * 0.5f; + lum0 = avg; + lum1 = avg; + } + + int ilum1 = static_cast < int >(floor(lum1 + 0.5f)); + int ilum0 = static_cast < int >(floor(lum0 + 0.5f)); + + // difference of more than a factor-of-2 results in immediate failure. + if (ilum1 - ilum0 > 2048) + return 0; + + int lowval, highval, diffval; + int v0, v1; + int v0e, v1e; + int v0d, v1d; + + // first, try to encode the high-precision submode + lowval = (ilum0 + 16) >> 5; + highval = (ilum1 + 16) >> 5; + + if (lowval < 0) + lowval = 0; + else if (lowval > 2047) + lowval = 2047; + + if (highval < 0) + highval = 0; + else if (highval > 2047) + highval = 2047; + + v0 = lowval & 0x7F; + v0e = color_quantization_tables[quantization_level][v0]; + v0d = color_unquantization_tables[quantization_level][v0e]; + if ((v0d & 0x80) == 0x80) + goto LOW_PRECISION_SUBMODE; + + lowval = (lowval & ~0x7F) | (v0d & 0x7F); + diffval = highval - lowval; + if (diffval < 0 || diffval > 15) + goto LOW_PRECISION_SUBMODE; + + v1 = ((lowval >> 3) & 0xF0) | diffval; + v1e = color_quantization_tables[quantization_level][v1]; + v1d = color_unquantization_tables[quantization_level][v1e]; + if ((v1d & 0xF0) != (v1 & 0xF0)) + goto LOW_PRECISION_SUBMODE; + + output[0] = v0e; + output[1] = v1e; + return 1; + + + // failed to encode the high-precision submode; well, then try to encode the + // low-precision submode. + LOW_PRECISION_SUBMODE: + + lowval = (ilum0 + 32) >> 6; + highval = (ilum1 + 32) >> 6; + if (lowval < 0) + lowval = 0; + else if (lowval > 1023) + lowval = 1023; + if (highval < 0) + highval = 0; + else if (highval > 1023) + highval = 1023; + + v0 = (lowval & 0x7F) | 0x80; + v0e = color_quantization_tables[quantization_level][v0]; + v0d = color_unquantization_tables[quantization_level][v0e]; + if ((v0d & 0x80) == 0) + return 0; + + lowval = (lowval & ~0x7F) | (v0d & 0x7F); + diffval = highval - lowval; + if (diffval < 0 || diffval > 31) + return 0; + + v1 = ((lowval >> 2) & 0xE0) | diffval; + v1e = color_quantization_tables[quantization_level][v1]; + v1d = color_unquantization_tables[quantization_level][v1e]; + if ((v1d & 0xE0) != (v1 & 0xE0)) + return 0;; + + output[0] = v0e; + output[1] = v1e; + return 1; +} + + +void quantize_hdr_alpha3(float alpha0, float alpha1, int output[2], int quantization_level) +{ + int i; + + if (alpha0 < 0) + alpha0 = 0; + else if (alpha0 > 65280) + alpha0 = 65280; + + if (alpha1 < 0) + alpha1 = 0; + else if (alpha1 > 65280) + alpha1 = 65280; + + int ialpha0 = static_cast < int >(floor(alpha0 + 0.5f)); + int ialpha1 = static_cast < int >(floor(alpha1 + 0.5f)); + + 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 (i = 2; i >= 0; i--) + { + val0 = (ialpha0 + (128 >> i)) >> (8 - i); + val1 = (ialpha1 + (128 >> i)) >> (8 - i); + + v6 = (val0 & 0x7F) | ((i & 1) << 7); + v6e = color_quantization_tables[quantization_level][v6]; + v6d = color_unquantization_tables[quantization_level][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 = color_quantization_tables[quantization_level][v7]; + v7d = color_unquantization_tables[quantization_level][v7e]; + + static const int testbits[3] = { 0xE0, 0xF0, 0xF8 }; + + if ((v7 ^ v7d) & testbits[i]) + continue; + + output[0] = v6e; + output[1] = 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; + + v6e = color_quantization_tables[quantization_level][v6]; + v7e = color_quantization_tables[quantization_level][v7]; + output[0] = v6e; + output[1] = v7e; + + return; +} + + + +void quantize_hdr_rgb_alpha3(float4 color0, float4 color1, int output[8], int quantization_level) +{ + quantize_hdr_rgb3(color0, color1, output, quantization_level); + quantize_hdr_alpha3(color0.w, color1.w, output + 6, quantization_level); +} + + + +/* + Quantize a color. When quantizing an RGB or RGBA color, the quantizer may choose a + delta-based representation; as such, it will report back the format it actually used. +*/ +int pack_color_endpoints(astc_decode_mode decode_mode, float4 color0, float4 color1, float4 rgbs_color, float4 rgbo_color, float2 luminances, // ! Unused + int format, int *output, int quantization_level) +{ + + IGNORE(luminances); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : format=%d quantization_level=%d\n", __func__, format, quantization_level); + printf("Color 0: <%g %g %g %g>\n", color0.x, color0.y, color0.z, color0.w); + printf("Color 1: <%g %g %g %g>\n", color1.x, color1.y, color1.z, color1.w); + + } + #endif + + // we do not support negative colors. + color0.x = MAX(color0.x, 0.0f); + color0.y = MAX(color0.y, 0.0f); + color0.z = MAX(color0.z, 0.0f); + color0.w = MAX(color0.w, 0.0f); + color1.x = MAX(color1.x, 0.0f); + color1.y = MAX(color1.y, 0.0f); + color1.z = MAX(color1.z, 0.0f); + color1.w = MAX(color1.w, 0.0f); + + + int retval; + + switch (format) + { + case FMT_RGB: + if (quantization_level <= 18) + { + if (try_quantize_rgb_delta_blue_contract(color0, color1, output, quantization_level)) + { + retval = FMT_RGB_DELTA; + break; + } + if (try_quantize_rgb_delta(color0, color1, output, quantization_level)) + { + retval = FMT_RGB_DELTA; + break; + } + } + if (try_quantize_rgb_blue_contract(color0, color1, output, quantization_level)) + { + retval = FMT_RGB; + break; + } + quantize_rgb(color0, color1, output, quantization_level); + retval = FMT_RGB; + break; + + case FMT_RGBA: + if (quantization_level <= 18) + { + if (try_quantize_rgba_delta_blue_contract(color0, color1, output, quantization_level)) + { + retval = FMT_RGBA_DELTA; + break; + } + if (try_quantize_rgba_delta(color0, color1, output, quantization_level)) + { + retval = FMT_RGBA_DELTA; + break; + } + } + if (try_quantize_rgba_blue_contract(color0, color1, output, quantization_level)) + { + retval = FMT_RGBA; + break; + } + quantize_rgba(color0, color1, output, quantization_level); + retval = FMT_RGBA; + break; + + case FMT_RGB_SCALE: + quantize_rgbs_new(rgbs_color, output, quantization_level); + // quantize_rgbs( color0, color1, output, quantization_level ); + retval = FMT_RGB_SCALE; + break; + + case FMT_HDR_RGB_SCALE: + quantize_hdr_rgbo3(rgbo_color, output, quantization_level); + + // quantize_hdr_rgb_scale( rgbo_color, output, quantization_level ); + retval = FMT_HDR_RGB_SCALE; + break; + + case FMT_HDR_RGB: + quantize_hdr_rgb3(color0, color1, output, quantization_level); + + // quantize_hdr_rgb_rgba( color0, color1, 0, output, quantization_level ); + retval = FMT_HDR_RGB; + break; + + case FMT_RGB_SCALE_ALPHA: + quantize_rgbs_alpha_new(color0, color1, rgbs_color, output, quantization_level); + // quantize_rgbs_alpha( color0, color1, output, quantization_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_range3(color0, color1, output, quantization_level)) + { + retval = FMT_HDR_LUMINANCE_SMALL_RANGE; + break; + } + quantize_hdr_luminance_large_range3(color0, color1, output, quantization_level); + retval = FMT_HDR_LUMINANCE_LARGE_RANGE; + break; + + case FMT_LUMINANCE: + quantize_luminance(color0, color1, output, quantization_level); + retval = FMT_LUMINANCE; + break; + + case FMT_LUMINANCE_ALPHA: + if (quantization_level <= 18) + { + if (try_quantize_luminance_alpha_delta(color0, color1, output, quantization_level)) + { + retval = FMT_LUMINANCE_ALPHA_DELTA; + break; + } + } + quantize_luminance_alpha(color0, color1, output, quantization_level); + retval = FMT_LUMINANCE_ALPHA; + break; + + case FMT_HDR_RGB_LDR_ALPHA: + quantize_hdr_rgb_ldr_alpha3(color0, color1, output, quantization_level); + retval = FMT_HDR_RGB_LDR_ALPHA; + break; + + case FMT_HDR_RGBA: + quantize_hdr_rgb_alpha3(color0, color1, output, quantization_level); + retval = FMT_HDR_RGBA; + break; + + default: + ASTC_CODEC_INTERNAL_ERROR; + quantize0(color0, color1, output, quantization_level); + retval = FMT_LUMINANCE; + break; + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + int i; + printf("Quantized to format %d\n", retval); + printf("Quantized color:"); + + for (i = 0; i < 8; i++) + printf(" %X", output[i]); + + ushort4 res0; + ushort4 res1; + int rgb_hdr; + int alpha_hdr; + int nan_endpoint; + + unpack_color_endpoints(decode_mode, retval, quantization_level, output, &rgb_hdr, &alpha_hdr, &nan_endpoint, &res0, &res1); + printf("rgb-hdr=%d alpha-hdr=%d nan-endpoint=%d\n", rgb_hdr, alpha_hdr, nan_endpoint); + + printf("Unquantized color 0: <%u %u %u %u>\n", res0.x, res0.y, res0.z, res0.w); + printf("Unquantized color 1: <%u %u %u %u>\n", res1.x, res1.y, res1.z, res1.w); + printf("\n\n"); + } + #endif + + return retval; +} diff --git a/third_party/astcenc/Source/astc_color_unquantize.cpp b/third_party/astcenc/Source/astc_color_unquantize.cpp new file mode 100644 index 0000000000..5090cfdfd7 --- /dev/null +++ b/third_party/astcenc/Source/astc_color_unquantize.cpp @@ -0,0 +1,970 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Color unquantization functions for ASTC. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include "mathlib.h" +#include "softfloat.h" + +int rgb_delta_unpack(const int input[6], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + // unquantize the color endpoints + int r0 = color_unquantization_tables[quantization_level][input[0]]; + int g0 = color_unquantization_tables[quantization_level][input[2]]; + int b0 = color_unquantization_tables[quantization_level][input[4]]; + + int r1 = color_unquantization_tables[quantization_level][input[1]]; + int g1 = color_unquantization_tables[quantization_level][input[3]]; + int b1 = color_unquantization_tables[quantization_level][input[5]]; + + // perform the bit-transfer procedure + r0 |= (r1 & 0x80) << 1; + g0 |= (g1 & 0x80) << 1; + b0 |= (b1 & 0x80) << 1; + r1 &= 0x7F; + g1 &= 0x7F; + b1 &= 0x7F; + if (r1 & 0x40) + r1 -= 0x80; + if (g1 & 0x40) + g1 -= 0x80; + if (b1 & 0x40) + b1 -= 0x80; + + r0 >>= 1; + g0 >>= 1; + b0 >>= 1; + r1 >>= 1; + g1 >>= 1; + b1 >>= 1; + + int rgbsum = r1 + g1 + b1; + + r1 += r0; + g1 += g0; + b1 += b0; + + + int retval; + + int r0e, g0e, b0e; + int r1e, g1e, b1e; + + if (rgbsum >= 0) + { + r0e = r0; + g0e = g0; + b0e = b0; + + r1e = r1; + g1e = g1; + b1e = b1; + + retval = 0; + } + else + { + r0e = (r1 + b1) >> 1; + g0e = (g1 + b1) >> 1; + b0e = b1; + + r1e = (r0 + b0) >> 1; + g1e = (g0 + b0) >> 1; + b1e = b0; + + retval = 1; + } + + if (r0e < 0) + r0e = 0; + else if (r0e > 255) + r0e = 255; + + if (g0e < 0) + g0e = 0; + else if (g0e > 255) + g0e = 255; + + if (b0e < 0) + b0e = 0; + else if (b0e > 255) + b0e = 255; + + if (r1e < 0) + r1e = 0; + else if (r1e > 255) + r1e = 255; + + if (g1e < 0) + g1e = 0; + else if (g1e > 255) + g1e = 255; + + if (b1e < 0) + b1e = 0; + else if (b1e > 255) + b1e = 255; + + output0->x = r0e; + output0->y = g0e; + output0->z = b0e; + output0->w = 0xFF; + + output1->x = r1e; + output1->y = g1e; + output1->z = b1e; + output1->w = 0xFF; + + return retval; +} + + +int rgb_unpack(const int input[6], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + + int ri0b = color_unquantization_tables[quantization_level][input[0]]; + int ri1b = color_unquantization_tables[quantization_level][input[1]]; + int gi0b = color_unquantization_tables[quantization_level][input[2]]; + int gi1b = color_unquantization_tables[quantization_level][input[3]]; + int bi0b = color_unquantization_tables[quantization_level][input[4]]; + int bi1b = color_unquantization_tables[quantization_level][input[5]]; + + if (ri0b + gi0b + bi0b > ri1b + gi1b + bi1b) + { + // blue-contraction + ri0b = (ri0b + bi0b) >> 1; + gi0b = (gi0b + bi0b) >> 1; + ri1b = (ri1b + bi1b) >> 1; + gi1b = (gi1b + bi1b) >> 1; + + output0->x = ri1b; + output0->y = gi1b; + output0->z = bi1b; + output0->w = 255; + + output1->x = ri0b; + output1->y = gi0b; + output1->z = bi0b; + output1->w = 255; + return 1; + } + else + { + output0->x = ri0b; + output0->y = gi0b; + output0->z = bi0b; + output0->w = 255; + + output1->x = ri1b; + output1->y = gi1b; + output1->z = bi1b; + output1->w = 255; + return 0; + } +} + + + + +void rgba_unpack(const int input[8], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int order = rgb_unpack(input, quantization_level, output0, output1); + if (order == 0) + { + output0->w = color_unquantization_tables[quantization_level][input[6]]; + output1->w = color_unquantization_tables[quantization_level][input[7]]; + } + else + { + output0->w = color_unquantization_tables[quantization_level][input[7]]; + output1->w = color_unquantization_tables[quantization_level][input[6]]; + } +} + + + +void rgba_delta_unpack(const int input[8], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int a0 = color_unquantization_tables[quantization_level][input[6]]; + int a1 = color_unquantization_tables[quantization_level][input[7]]; + a0 |= (a1 & 0x80) << 1; + a1 &= 0x7F; + if (a1 & 0x40) + a1 -= 0x80; + a0 >>= 1; + a1 >>= 1; + a1 += a0; + + if (a1 < 0) + a1 = 0; + else if (a1 > 255) + a1 = 255; + + int order = rgb_delta_unpack(input, quantization_level, output0, output1); + if (order == 0) + { + output0->w = a0; + output1->w = a1; + } + else + { + output0->w = a1; + output1->w = a0; + } +} + + +void rgb_scale_unpack(const int input[4], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int ir = color_unquantization_tables[quantization_level][input[0]]; + int ig = color_unquantization_tables[quantization_level][input[1]]; + int ib = color_unquantization_tables[quantization_level][input[2]]; + + int iscale = color_unquantization_tables[quantization_level][input[3]]; + + *output1 = ushort4(ir, ig, ib, 255); + *output0 = ushort4((ir * iscale) >> 8, (ig * iscale) >> 8, (ib * iscale) >> 8, 255); +} + + + +void rgb_scale_alpha_unpack(const int input[6], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + rgb_scale_unpack(input, quantization_level, output0, output1); + output0->w = color_unquantization_tables[quantization_level][input[4]]; + output1->w = color_unquantization_tables[quantization_level][input[5]]; + +} + + +void luminance_unpack(const int input[2], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int lum0 = color_unquantization_tables[quantization_level][input[0]]; + int lum1 = color_unquantization_tables[quantization_level][input[1]]; + *output0 = ushort4(lum0, lum0, lum0, 255); + *output1 = ushort4(lum1, lum1, lum1, 255); +} + + +void luminance_delta_unpack(const int input[2], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int v0 = color_unquantization_tables[quantization_level][input[0]]; + int v1 = color_unquantization_tables[quantization_level][input[1]]; + int l0 = (v0 >> 2) | (v1 & 0xC0); + int l1 = l0 + (v1 & 0x3F); + + if (l1 > 255) + l1 = 255; + + *output0 = ushort4(l0, l0, l0, 255); + *output1 = ushort4(l1, l1, l1, 255); +} + + + + +void luminance_alpha_unpack(const int input[4], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int lum0 = color_unquantization_tables[quantization_level][input[0]]; + int lum1 = color_unquantization_tables[quantization_level][input[1]]; + int alpha0 = color_unquantization_tables[quantization_level][input[2]]; + int alpha1 = color_unquantization_tables[quantization_level][input[3]]; + *output0 = ushort4(lum0, lum0, lum0, alpha0); + *output1 = ushort4(lum1, lum1, lum1, alpha1); +} + + +void luminance_alpha_delta_unpack(const int input[4], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int lum0 = color_unquantization_tables[quantization_level][input[0]]; + int lum1 = color_unquantization_tables[quantization_level][input[1]]; + int alpha0 = color_unquantization_tables[quantization_level][input[2]]; + int alpha1 = color_unquantization_tables[quantization_level][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; + + if (lum1 < 0) + lum1 = 0; + else if (lum1 > 255) + lum1 = 255; + + if (alpha1 < 0) + alpha1 = 0; + else if (alpha1 > 255) + alpha1 = 255; + + *output0 = ushort4(lum0, lum0, lum0, alpha0); + *output1 = ushort4(lum1, lum1, lum1, alpha1); +} + + + + +// RGB-offset format +void hdr_rgbo_unpack3(const int input[4], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int v0 = color_unquantization_tables[quantization_level][input[0]]; + int v1 = color_unquantization_tables[quantization_level][input[1]]; + int v2 = color_unquantization_tables[quantization_level][input[2]]; + int v3 = color_unquantization_tables[quantization_level][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 = ushort4(red0 << 4, green0 << 4, blue0 << 4, 0x7800); + *output1 = ushort4(red << 4, green << 4, blue << 4, 0x7800); +} + + + +void hdr_rgb_unpack3(const int input[6], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + + int v0 = color_unquantization_tables[quantization_level][input[0]]; + int v1 = color_unquantization_tables[quantization_level][input[1]]; + int v2 = color_unquantization_tables[quantization_level][input[2]]; + int v3 = color_unquantization_tables[quantization_level][input[3]]; + int v4 = color_unquantization_tables[quantization_level][input[4]]; + int v5 = color_unquantization_tables[quantization_level][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 = ushort4(v0 << 8, v2 << 8, (v4 & 0x7F) << 9, 0x7800); + *output1 = ushort4(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; + if (ohmod & 0x5B) + b1 |= bit1 << 6; + + if (ohmod & 0x12) + b0 |= bit2 << 7; + if (ohmod & 0x12) + b1 |= bit3 << 7; + + if (ohmod & 0xAF) + d0 |= bit4 << 5; + if (ohmod & 0xAF) + d1 |= bit5 << 5; + if (ohmod & 0x5) + d0 |= bit2 << 6; + if (ohmod & 0x5) + 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] + if (red0 < 0) + red0 = 0; + else if (red0 > 0xFFF) + red0 = 0xFFF; + + if (green0 < 0) + green0 = 0; + else if (green0 > 0xFFF) + green0 = 0xFFF; + + if (blue0 < 0) + blue0 = 0; + else if (blue0 > 0xFFF) + blue0 = 0xFFF; + + if (red1 < 0) + red1 = 0; + else if (red1 > 0xFFF) + red1 = 0xFFF; + + if (green1 < 0) + green1 = 0; + else if (green1 > 0xFFF) + green1 = 0xFFF; + + if (blue1 < 0) + blue1 = 0; + else if (blue1 > 0xFFF) + blue1 = 0xFFF; + + + // 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 = ushort4(red0 << 4, green0 << 4, blue0 << 4, 0x7800); + *output1 = ushort4(red1 << 4, green1 << 4, blue1 << 4, 0x7800); +} + + + + +void hdr_rgb_ldr_alpha_unpack3(const int input[8], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + hdr_rgb_unpack3(input, quantization_level, output0, output1); + + int v6 = color_unquantization_tables[quantization_level][input[6]]; + int v7 = color_unquantization_tables[quantization_level][input[7]]; + output0->w = v6; + output1->w = v7; +} + + + +void hdr_luminance_small_range_unpack(const int input[2], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int v0 = color_unquantization_tables[quantization_level][input[0]]; + int v1 = color_unquantization_tables[quantization_level][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 = ushort4(y0 << 4, y0 << 4, y0 << 4, 0x7800); + *output1 = ushort4(y1 << 4, y1 << 4, y1 << 4, 0x7800); +} + + +void hdr_luminance_large_range_unpack(const int input[2], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + int v0 = color_unquantization_tables[quantization_level][input[0]]; + int v1 = color_unquantization_tables[quantization_level][input[1]]; + + int y0, y1; + if (v1 >= v0) + { + y0 = v0 << 4; + y1 = v1 << 4; + } + else + { + y0 = (v1 << 4) + 8; + y1 = (v0 << 4) - 8; + } + *output0 = ushort4(y0 << 4, y0 << 4, y0 << 4, 0x7800); + *output1 = ushort4(y1 << 4, y1 << 4, y1 << 4, 0x7800); +} + + + +void hdr_alpha_unpack(const int input[2], int quantization_level, int *a0, int *a1) +{ + + int v6 = color_unquantization_tables[quantization_level][input[0]]; + int v7 = color_unquantization_tables[quantization_level][input[1]]; + + int selector = ((v6 >> 7) & 1) | ((v7 >> 6) & 2); + v6 &= 0x7F; + v7 &= 0x7F; + if (selector == 3) + { + *a0 = v6 << 5; + *a1 = 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; + + *a0 = v6; + *a1 = v7; + } + + *a0 <<= 4; + *a1 <<= 4; +} + + + +void hdr_rgb_hdr_alpha_unpack3(const int input[8], int quantization_level, ushort4 * output0, ushort4 * output1) +{ + hdr_rgb_unpack3(input, quantization_level, output0, output1); + + int alpha0, alpha1; + hdr_alpha_unpack(input + 6, quantization_level, &alpha0, &alpha1); + + output0->w = alpha0; + output1->w = alpha1; +} + + + + + + +void unpack_color_endpoints(astc_decode_mode decode_mode, int format, int quantization_level, const int *input, int *rgb_hdr, int *alpha_hdr, int *nan_endpoint, ushort4 * output0, ushort4 * output1) +{ + *nan_endpoint = 0; + + switch (format) + { + case FMT_LUMINANCE: + *rgb_hdr = 0; + *alpha_hdr = 0; + luminance_unpack(input, quantization_level, output0, output1); + break; + + case FMT_LUMINANCE_DELTA: + *rgb_hdr = 0; + *alpha_hdr = 0; + luminance_delta_unpack(input, quantization_level, output0, output1); + break; + + case FMT_HDR_LUMINANCE_SMALL_RANGE: + *rgb_hdr = 1; + *alpha_hdr = -1; + hdr_luminance_small_range_unpack(input, quantization_level, output0, output1); + break; + + case FMT_HDR_LUMINANCE_LARGE_RANGE: + *rgb_hdr = 1; + *alpha_hdr = -1; + hdr_luminance_large_range_unpack(input, quantization_level, output0, output1); + break; + + case FMT_LUMINANCE_ALPHA: + *rgb_hdr = 0; + *alpha_hdr = 0; + luminance_alpha_unpack(input, quantization_level, output0, output1); + break; + + case FMT_LUMINANCE_ALPHA_DELTA: + *rgb_hdr = 0; + *alpha_hdr = 0; + luminance_alpha_delta_unpack(input, quantization_level, output0, output1); + break; + + case FMT_RGB_SCALE: + *rgb_hdr = 0; + *alpha_hdr = 0; + rgb_scale_unpack(input, quantization_level, output0, output1); + break; + + case FMT_RGB_SCALE_ALPHA: + *rgb_hdr = 0; + *alpha_hdr = 0; + rgb_scale_alpha_unpack(input, quantization_level, output0, output1); + break; + + case FMT_HDR_RGB_SCALE: + *rgb_hdr = 1; + *alpha_hdr = -1; + hdr_rgbo_unpack3(input, quantization_level, output0, output1); + break; + + case FMT_RGB: + *rgb_hdr = 0; + *alpha_hdr = 0; + rgb_unpack(input, quantization_level, output0, output1); + break; + + case FMT_RGB_DELTA: + *rgb_hdr = 0; + *alpha_hdr = 0; + rgb_delta_unpack(input, quantization_level, output0, output1); + break; + + case FMT_HDR_RGB: + *rgb_hdr = 1; + *alpha_hdr = -1; + hdr_rgb_unpack3(input, quantization_level, output0, output1); + break; + + case FMT_RGBA: + *rgb_hdr = 0; + *alpha_hdr = 0; + rgba_unpack(input, quantization_level, output0, output1); + break; + + case FMT_RGBA_DELTA: + *rgb_hdr = 0; + *alpha_hdr = 0; + rgba_delta_unpack(input, quantization_level, output0, output1); + break; + + case FMT_HDR_RGB_LDR_ALPHA: + *rgb_hdr = 1; + *alpha_hdr = 0; + hdr_rgb_ldr_alpha_unpack3(input, quantization_level, output0, output1); + break; + + case FMT_HDR_RGBA: + *rgb_hdr = 1; + *alpha_hdr = 1; + hdr_rgb_hdr_alpha_unpack3(input, quantization_level, output0, output1); + break; + + default: + ASTC_CODEC_INTERNAL_ERROR; + } + + + + if (*alpha_hdr == -1) + { + if (alpha_force_use_of_hdr) + { + output0->w = 0x7800; + output1->w = 0x7800; + *alpha_hdr = 1; + } + else + { + output0->w = 0x00FF; + output1->w = 0x00FF; + *alpha_hdr = 0; + } + } + + + + switch (decode_mode) + { + case DECODE_LDR_SRGB: + if (*rgb_hdr == 1) + { + output0->x = 0xFF00; + output0->y = 0x0000; + output0->z = 0xFF00; + output0->w = 0xFF00; + output1->x = 0xFF00; + output1->y = 0x0000; + output1->z = 0xFF00; + output1->w = 0xFF00; + } + else + { + output0->x *= 257; + output0->y *= 257; + output0->z *= 257; + output0->w *= 257; + output1->x *= 257; + output1->y *= 257; + output1->z *= 257; + output1->w *= 257; + } + *rgb_hdr = 0; + *alpha_hdr = 0; + break; + + case DECODE_LDR: + if (*rgb_hdr == 1) + { + output0->x = 0xFFFF; + output0->y = 0xFFFF; + output0->z = 0xFFFF; + output0->w = 0xFFFF; + output1->x = 0xFFFF; + output1->y = 0xFFFF; + output1->z = 0xFFFF; + output1->w = 0xFFFF; + *nan_endpoint = 1; + } + else + { + output0->x *= 257; + output0->y *= 257; + output0->z *= 257; + output0->w *= 257; + output1->x *= 257; + output1->y *= 257; + output1->z *= 257; + output1->w *= 257; + } + *rgb_hdr = 0; + *alpha_hdr = 0; + break; + + case DECODE_HDR: + + if (*rgb_hdr == 0) + { + output0->x *= 257; + output0->y *= 257; + output0->z *= 257; + output1->x *= 257; + output1->y *= 257; + output1->z *= 257; + } + if (*alpha_hdr == 0) + { + output0->w *= 257; + output1->w *= 257; + } + break; + } +} diff --git a/third_party/astcenc/Source/astc_compress_symbolic.cpp b/third_party/astcenc/Source/astc_compress_symbolic.cpp new file mode 100644 index 0000000000..152ca05472 --- /dev/null +++ b/third_party/astcenc/Source/astc_compress_symbolic.cpp @@ -0,0 +1,1792 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Compress a block of colors, expressed as a symbolic block, for ASTC. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include "softfloat.h" +#include +#include +#include + +#ifdef DEBUG_CAPTURE_NAN + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + + #include +#endif + +#include + +int realign_weights(astc_decode_mode decode_mode, + int xdim, int ydim, int zdim, const imageblock * blk, const error_weight_block * ewb, symbolic_compressed_block * scb, uint8_t * weight_set8, uint8_t * plane2_weight_set8) +{ + int i, j; + + // get the appropriate partition descriptor. + int partition_count = scb->partition_count; + const partition_info *pt = get_partition_table(xdim, ydim, zdim, partition_count); + pt += scb->partition_index; + + // get the appropriate block descriptor + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + const decimation_table *const *ixtab2 = bsd->decimation_tables; + + const decimation_table *it = ixtab2[bsd->block_modes[scb->block_mode].decimation_mode]; + + int is_dual_plane = bsd->block_modes[scb->block_mode].is_dual_plane; + + // get quantization-parameters + int weight_quantization_level = bsd->block_modes[scb->block_mode].quantization_mode; + + + // decode the color endpoints + ushort4 color_endpoint0[4]; + ushort4 color_endpoint1[4]; + int rgb_hdr[4]; + int alpha_hdr[4]; + int nan_endpoint[4]; + + + for (i = 0; i < partition_count; i++) + unpack_color_endpoints(decode_mode, + scb->color_formats[i], scb->color_quantization_level, scb->color_values[i], &rgb_hdr[i], &alpha_hdr[i], &nan_endpoint[i], &(color_endpoint0[i]), &(color_endpoint1[i])); + + + float uq_plane1_weights[MAX_WEIGHTS_PER_BLOCK]; + float uq_plane2_weights[MAX_WEIGHTS_PER_BLOCK]; + int weight_count = it->num_weights; + + // read and unquantize the weights. + + const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[weight_quantization_level]); + + for (i = 0; i < weight_count; i++) + { + uq_plane1_weights[i] = qat->unquantized_value_flt[weight_set8[i]]; + } + if (is_dual_plane) + { + for (i = 0; i < weight_count; i++) + uq_plane2_weights[i] = qat->unquantized_value_flt[plane2_weight_set8[i]]; + } + + + int plane2_color_component = is_dual_plane ? scb->plane2_color_component : -1; + + // for each weight, unquantize the weight, use it to compute a color and a color error. + // then, increment the weight until the color error stops decreasing + // then, decrement the weight until the color error stops increasing + + #define COMPUTE_ERROR( errorvar ) \ + errorvar = 0.0f; \ + for(j=0;jweight_texel[i][j]; \ + int partition = pt->partition_of_texel[texel]; \ + float plane1_weight = compute_value_of_texel_flt( texel, it, uq_plane1_weights ); \ + float plane2_weight = 0.0f; \ + if( is_dual_plane ) \ + plane2_weight = compute_value_of_texel_flt( texel, it, uq_plane2_weights ); \ + int int_plane1_weight = static_cast(floor( plane1_weight*64.0f + 0.5f ) ); \ + int int_plane2_weight = static_cast(floor( plane2_weight*64.0f + 0.5f ) ); \ + ushort4 lrp_color = lerp_color_int( \ + decode_mode, \ + color_endpoint0[partition], \ + color_endpoint1[partition], \ + int_plane1_weight, \ + int_plane2_weight, \ + plane2_color_component ); \ + float4 color = float4( lrp_color.x, lrp_color.y, lrp_color.z, lrp_color.w ); \ + float4 origcolor = float4( \ + blk->work_data[4*texel], \ + blk->work_data[4*texel+1], \ + blk->work_data[4*texel+2], \ + blk->work_data[4*texel+3] ); \ + float4 error_weight = ewb->error_weights[texel]; \ + float4 colordiff = color - origcolor; \ + errorvar += dot( colordiff*colordiff, error_weight ); \ + } + + + int adjustments = 0; + + for (i = 0; i < weight_count; i++) + { + int current_wt = weight_set8[i]; + int texels_to_evaluate = it->weight_num_texels[i]; + + float current_error; + + COMPUTE_ERROR(current_error); + + // increment until error starts increasing. + while (1) + { + int next_wt = qat->next_quantized_value[current_wt]; + if (next_wt == current_wt) + break; + uq_plane1_weights[i] = qat->unquantized_value_flt[next_wt]; + float next_error; + COMPUTE_ERROR(next_error); + if (next_error < current_error) + { + // succeeded, increment the weight + current_wt = next_wt; + current_error = next_error; + adjustments++; + } + else + { + // failed, back out the attempted increment + uq_plane1_weights[i] = qat->unquantized_value_flt[current_wt]; + break; + } + } + // decrement until error starts increasing + while (1) + { + int prev_wt = qat->prev_quantized_value[current_wt]; + if (prev_wt == current_wt) + break; + uq_plane1_weights[i] = qat->unquantized_value_flt[prev_wt]; + float prev_error; + COMPUTE_ERROR(prev_error); + if (prev_error < current_error) + { + // succeeded, decrement the weight + current_wt = prev_wt; + current_error = prev_error; + adjustments++; + } + else + { + // failed, back out the attempted decrement + uq_plane1_weights[i] = qat->unquantized_value_flt[current_wt]; + break; + } + } + + weight_set8[i] = current_wt; + } + + if (!is_dual_plane) + return adjustments; + + // processing of the second plane of weights + for (i = 0; i < weight_count; i++) + { + int current_wt = plane2_weight_set8[i]; + int texels_to_evaluate = it->weight_num_texels[i]; + + float current_error; + + COMPUTE_ERROR(current_error); + + // increment until error starts increasing. + while (1) + { + int next_wt = qat->next_quantized_value[current_wt]; + if (next_wt == current_wt) + break; + uq_plane2_weights[i] = qat->unquantized_value_flt[next_wt]; + float next_error; + COMPUTE_ERROR(next_error); + if (next_error < current_error) + { + // succeeded, increment the weight + current_wt = next_wt; + current_error = next_error; + adjustments++; + } + else + { + // failed, back out the attempted increment + uq_plane2_weights[i] = qat->unquantized_value_flt[current_wt]; + break; + } + } + // decrement until error starts increasing + while (1) + { + int prev_wt = qat->prev_quantized_value[current_wt]; + if (prev_wt == current_wt) + break; + uq_plane2_weights[i] = qat->unquantized_value_flt[prev_wt]; + float prev_error; + COMPUTE_ERROR(prev_error); + if (prev_error < current_error) + { + // succeeded, decrement the weight + current_wt = prev_wt; + current_error = prev_error; + adjustments++; + } + else + { + // failed, back out the attempted decrement + uq_plane2_weights[i] = qat->unquantized_value_flt[current_wt]; + break; + } + } + + plane2_weight_set8[i] = current_wt; + } + + return adjustments; +} + +/* + function for compressing a block symbolically, given that we have already decided on a partition +*/ + + + +static void compress_symbolic_block_fixed_partition_1_plane(astc_decode_mode decode_mode, + float mode_cutoff, + int max_refinement_iters, + int xdim, int ydim, int zdim, + int partition_count, int partition_index, + const imageblock * blk, const error_weight_block * ewb, symbolic_compressed_block * scb, + compress_fixed_partition_buffers * tmpbuf) +{ + int i, j, k; + + + static const int free_bits_for_partition_count[5] = { 0, 115 - 4, 111 - 4 - PARTITION_BITS, 108 - 4 - PARTITION_BITS, 105 - 4 - PARTITION_BITS }; + + const partition_info *pi = get_partition_table(xdim, ydim, zdim, partition_count); + pi += partition_index; + + // first, compute ideal weights and endpoint colors, under thre assumption that + // there is no quantization or decimation going on. + endpoints_and_weights *ei = tmpbuf->ei1; + endpoints_and_weights *eix = tmpbuf->eix1; + compute_endpoints_and_ideal_weights_1_plane(xdim, ydim, zdim, pi, blk, ewb, ei); + + // next, compute ideal weights and endpoint colors for every decimation. + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + const decimation_table *const *ixtab2 = bsd->decimation_tables; + // int block_mode_count = bsd->single_plane_block_mode_count; + + + float *decimated_quantized_weights = tmpbuf->decimated_quantized_weights; + float *decimated_weights = tmpbuf->decimated_weights; + float *flt_quantized_decimated_quantized_weights = tmpbuf->flt_quantized_decimated_quantized_weights; + uint8_t *u8_quantized_decimated_quantized_weights = tmpbuf->u8_quantized_decimated_quantized_weights; + + // for each decimation mode, compute an ideal set of weights + // (that is, weights computed with the assumption that they are not quantized) + for (i = 0; i < MAX_DECIMATION_MODES; i++) + { + if (bsd->permit_encode[i] == 0 || bsd->decimation_mode_maxprec_1plane[i] < 0 || bsd->decimation_mode_percentile[i] > mode_cutoff) + continue; + eix[i] = *ei; + compute_ideal_weights_for_decimation_table(&(eix[i]), ixtab2[i], decimated_quantized_weights + i * MAX_WEIGHTS_PER_BLOCK, decimated_weights + i * MAX_WEIGHTS_PER_BLOCK); + + } + + // compute maximum colors for the endpoints and ideal weights. + // for each endpoint-and-ideal-weight pair, compute the smallest weight value + // that will result in a color value greater than 1. + + + float4 min_ep = float4(10, 10, 10, 10); + for (i = 0; i < partition_count; i++) + { + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + float4 ep = (float4(1, 1, 1, 1) - ei->ep.endpt0[i]) / (ei->ep.endpt1[i] - ei->ep.endpt0[i]); + if (ep.x > 0.5f && ep.x < min_ep.x) + min_ep.x = ep.x; + if (ep.y > 0.5f && ep.y < min_ep.y) + min_ep.y = ep.y; + if (ep.z > 0.5f && ep.z < min_ep.z) + min_ep.z = ep.z; + if (ep.w > 0.5f && ep.w < min_ep.w) + min_ep.w = ep.w; + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + } + + float min_wt_cutoff = MIN(MIN(min_ep.x, min_ep.y), MIN(min_ep.z, min_ep.w)); + + // for each mode, use the angular method to compute a shift. + float weight_low_value[MAX_WEIGHT_MODES]; + float weight_high_value[MAX_WEIGHT_MODES]; + + compute_angular_endpoints_1plane(mode_cutoff, bsd, decimated_quantized_weights, decimated_weights, weight_low_value, weight_high_value); + + // 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. + + int qwt_bitcounts[MAX_WEIGHT_MODES]; + float qwt_errors[MAX_WEIGHT_MODES]; + + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (bsd->block_modes[i].permit_encode == 0 || bsd->block_modes[i].is_dual_plane != 0 || bsd->block_modes[i].percentile > mode_cutoff) + { + qwt_errors[i] = 1e38f; + continue; + } + if (weight_high_value[i] > 1.02f * min_wt_cutoff) + weight_high_value[i] = 1.0f; + + int decimation_mode = bsd->block_modes[i].decimation_mode; + if (bsd->decimation_mode_percentile[decimation_mode] > mode_cutoff) + ASTC_CODEC_INTERNAL_ERROR; + + + // compute weight bitcount for the mode + int bits_used_by_weights = compute_ise_bitcount(ixtab2[decimation_mode]->num_weights, + (quantization_method) bsd->block_modes[i].quantization_mode); + int bitcount = free_bits_for_partition_count[partition_count] - bits_used_by_weights; + if (bitcount <= 0 || bits_used_by_weights < 24 || bits_used_by_weights > 96) + { + qwt_errors[i] = 1e38f; + continue; + } + qwt_bitcounts[i] = bitcount; + + + // then, generate the optimized set of weights for the weight mode. + compute_ideal_quantized_weights_for_decimation_table(&(eix[decimation_mode]), + ixtab2[decimation_mode], + weight_low_value[i], weight_high_value[i], + decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * decimation_mode, + flt_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * i, + u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * i, + bsd->block_modes[i].quantization_mode); + + // then, compute weight-errors for the weight mode. + qwt_errors[i] = compute_error_of_weight_set(&(eix[decimation_mode]), ixtab2[decimation_mode], flt_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * i); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Block mode %d -> weight error = %f\n", i, qwt_errors[i]); + #endif + } + + // for each weighting mode, determine the optimal combination of color endpoint encodings + // and weight encodings; return results for the 4 best-looking modes. + + int partition_format_specifiers[4][4]; + int quantized_weight[4]; + int color_quantization_level[4]; + int color_quantization_level_mod[4]; + determine_optimal_set_of_endpoint_formats_to_use(xdim, ydim, zdim, pi, blk, ewb, &(ei->ep), -1, // used to flag that we are in single-weight mode + qwt_bitcounts, qwt_errors, partition_format_specifiers, quantized_weight, color_quantization_level, color_quantization_level_mod); + + + // then iterate over the 4 believed-to-be-best modes to find out which one is + // actually best. + for (i = 0; i < 4; i++) + { + uint8_t *u8_weight_src; + int weights_to_copy; + + if (quantized_weight[i] < 0) + { + scb->error_block = 1; + scb++; + continue; + } + + int decimation_mode = bsd->block_modes[quantized_weight[i]].decimation_mode; + int weight_quantization_mode = bsd->block_modes[quantized_weight[i]].quantization_mode; + const decimation_table *it = ixtab2[decimation_mode]; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Selected mode = %d\n", quantized_weight[i]); + printf("Selected decimation mode = %d\n", decimation_mode); + printf("Selected weight-quantization mode = %d\n", weight_quantization_mode); + } + #endif + + u8_weight_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * quantized_weight[i]; + + weights_to_copy = it->num_weights; + + // recompute the ideal color endpoints before storing them. + float4 rgbs_colors[4]; + float4 rgbo_colors[4]; + float2 lum_intervals[4]; + + int l; + for (l = 0; l < max_refinement_iters; l++) + { + recompute_ideal_colors(xdim, ydim, zdim, weight_quantization_mode, &(eix[decimation_mode].ep), rgbs_colors, rgbo_colors, lum_intervals, u8_weight_src, NULL, -1, pi, it, blk, ewb); + + // quantize the chosen color + + // store the colors for the block + for (j = 0; j < partition_count; j++) + { + scb->color_formats[j] = pack_color_endpoints(decode_mode, + eix[decimation_mode].ep.endpt0[j], + eix[decimation_mode].ep.endpt1[j], + rgbs_colors[j], rgbo_colors[j], lum_intervals[j], partition_format_specifiers[i][j], scb->color_values[j], color_quantization_level[i]); + } + + + // 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; + // if they do, then exploit it. + scb->color_formats_matched = 0; + + if ((partition_count >= 2 && scb->color_formats[0] == scb->color_formats[1] + && color_quantization_level != color_quantization_level_mod) + && (partition_count == 2 || (scb->color_formats[0] == scb->color_formats[2] && (partition_count == 3 || (scb->color_formats[0] == scb->color_formats[3]))))) + { + int colorvals[4][12]; + int color_formats_mod[4]; + for (j = 0; j < partition_count; j++) + { + color_formats_mod[j] = pack_color_endpoints(decode_mode, + eix[decimation_mode].ep.endpt0[j], + eix[decimation_mode].ep.endpt1[j], + rgbs_colors[j], rgbo_colors[j], lum_intervals[j], partition_format_specifiers[i][j], colorvals[j], color_quantization_level_mod[i]); + } + if (color_formats_mod[0] == color_formats_mod[1] + && (partition_count == 2 || (color_formats_mod[0] == color_formats_mod[2] && (partition_count == 3 || (color_formats_mod[0] == color_formats_mod[3]))))) + { + scb->color_formats_matched = 1; + for (j = 0; j < 4; j++) + for (k = 0; k < 12; k++) + scb->color_values[j][k] = colorvals[j][k]; + for (j = 0; j < 4; j++) + scb->color_formats[j] = color_formats_mod[j]; + } + } + + + // store header fields + scb->partition_count = partition_count; + scb->partition_index = partition_index; + scb->color_quantization_level = scb->color_formats_matched ? color_quantization_level_mod[i] : color_quantization_level[i]; + scb->block_mode = quantized_weight[i]; + scb->error_block = 0; + + if (scb->color_quantization_level < 4) + { + scb->error_block = 1; // should never happen, but cannot prove it impossible. + } + + // perform a final pass over the weights to try to improve them. + int adjustments = realign_weights(decode_mode, + xdim, ydim, zdim, + blk, ewb, scb, + u8_weight_src, + NULL); + + if (adjustments == 0) + break; + } + + for (j = 0; j < weights_to_copy; j++) + scb->plane1_weights[j] = u8_weight_src[j]; + + scb++; + } + +} + + + + + + +static void compress_symbolic_block_fixed_partition_2_planes(astc_decode_mode decode_mode, + float mode_cutoff, + int max_refinement_iters, + int xdim, int ydim, int zdim, + int partition_count, int partition_index, + int separate_component, const imageblock * blk, const error_weight_block * ewb, + symbolic_compressed_block * scb, + compress_fixed_partition_buffers * tmpbuf) +{ + int i, j, k; + + static const int free_bits_for_partition_count[5] = + { 0, 113 - 4, 109 - 4 - PARTITION_BITS, 106 - 4 - PARTITION_BITS, 103 - 4 - PARTITION_BITS }; + + const partition_info *pi = get_partition_table(xdim, ydim, zdim, partition_count); + pi += partition_index; + + // first, compute ideal weights and endpoint colors + endpoints_and_weights *ei1 = tmpbuf->ei1; + endpoints_and_weights *ei2 = tmpbuf->ei2; + endpoints_and_weights *eix1 = tmpbuf->eix1; + endpoints_and_weights *eix2 = tmpbuf->eix2; + compute_endpoints_and_ideal_weights_2_planes(xdim, ydim, zdim, pi, blk, ewb, separate_component, ei1, ei2); + + // next, compute ideal weights and endpoint colors for every decimation. + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + const decimation_table *const *ixtab2 = bsd->decimation_tables; + + + float *decimated_quantized_weights = tmpbuf->decimated_quantized_weights; + float *decimated_weights = tmpbuf->decimated_weights; + float *flt_quantized_decimated_quantized_weights = tmpbuf->flt_quantized_decimated_quantized_weights; + uint8_t *u8_quantized_decimated_quantized_weights = tmpbuf->u8_quantized_decimated_quantized_weights; + + // for each decimation mode, compute an ideal set of weights + for (i = 0; i < MAX_DECIMATION_MODES; i++) + { + if (bsd->permit_encode[i] == 0 || bsd->decimation_mode_maxprec_2planes[i] < 0 || bsd->decimation_mode_percentile[i] > mode_cutoff) + continue; + + eix1[i] = *ei1; + eix2[i] = *ei2; + compute_ideal_weights_for_decimation_table(&(eix1[i]), ixtab2[i], decimated_quantized_weights + (2 * i) * MAX_WEIGHTS_PER_BLOCK, decimated_weights + (2 * i) * MAX_WEIGHTS_PER_BLOCK); + compute_ideal_weights_for_decimation_table(&(eix2[i]), ixtab2[i], decimated_quantized_weights + (2 * i + 1) * MAX_WEIGHTS_PER_BLOCK, decimated_weights + (2 * i + 1) * MAX_WEIGHTS_PER_BLOCK); + } + + // compute maximum colors for the endpoints and ideal weights. + // for each endpoint-and-ideal-weight pair, compute the smallest weight value + // that will result in a color value greater than 1. + + float4 min_ep1 = float4(10, 10, 10, 10); + float4 min_ep2 = float4(10, 10, 10, 10); + for (i = 0; i < partition_count; i++) + { + + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + float4 ep1 = (float4(1, 1, 1, 1) - ei1->ep.endpt0[i]) / (ei1->ep.endpt1[i] - ei1->ep.endpt0[i]); + if (ep1.x > 0.5f && ep1.x < min_ep1.x) + min_ep1.x = ep1.x; + if (ep1.y > 0.5f && ep1.y < min_ep1.y) + min_ep1.y = ep1.y; + if (ep1.z > 0.5f && ep1.z < min_ep1.z) + min_ep1.z = ep1.z; + if (ep1.w > 0.5f && ep1.w < min_ep1.w) + min_ep1.w = ep1.w; + float4 ep2 = (float4(1, 1, 1, 1) - ei2->ep.endpt0[i]) / (ei2->ep.endpt1[i] - ei2->ep.endpt0[i]); + if (ep2.x > 0.5f && ep2.x < min_ep2.x) + min_ep2.x = ep2.x; + if (ep2.y > 0.5f && ep2.y < min_ep2.y) + min_ep2.y = ep2.y; + if (ep2.z > 0.5f && ep2.z < min_ep2.z) + min_ep2.z = ep2.z; + if (ep2.w > 0.5f && ep2.w < min_ep2.w) + min_ep2.w = ep2.w; + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + } + + float min_wt_cutoff1, min_wt_cutoff2; + switch (separate_component) + { + case 0: + min_wt_cutoff2 = min_ep2.x; + min_ep1.x = 1e30f; + break; + case 1: + min_wt_cutoff2 = min_ep2.y; + min_ep1.y = 1e30f; + break; + case 2: + min_wt_cutoff2 = min_ep2.z; + min_ep1.z = 1e30f; + break; + case 3: + min_wt_cutoff2 = min_ep2.w; + min_ep1.w = 1e30f; + break; + default: + min_wt_cutoff2 = 1e30f; + } + + min_wt_cutoff1 = MIN(MIN(min_ep1.x, min_ep1.y), MIN(min_ep1.z, min_ep1.w)); + + float weight_low_value1[MAX_WEIGHT_MODES]; + float weight_high_value1[MAX_WEIGHT_MODES]; + float weight_low_value2[MAX_WEIGHT_MODES]; + float weight_high_value2[MAX_WEIGHT_MODES]; + + compute_angular_endpoints_2planes(mode_cutoff, bsd, decimated_quantized_weights, decimated_weights, weight_low_value1, weight_high_value1, weight_low_value2, weight_high_value2); + + // for each mode (which specifies a decimation and a quantization): + // * generate an optimized set of quantized weights. + // * compute quantization errors for each mode + // * compute number of bits needed for the quantized weights. + + int qwt_bitcounts[MAX_WEIGHT_MODES]; + float qwt_errors[MAX_WEIGHT_MODES]; + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (bsd->block_modes[i].permit_encode == 0 || bsd->block_modes[i].is_dual_plane != 1 || bsd->block_modes[i].percentile > mode_cutoff) + { + qwt_errors[i] = 1e38f; + continue; + } + int decimation_mode = bsd->block_modes[i].decimation_mode; + + 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; + + // compute weight bitcount for the mode + int bits_used_by_weights = compute_ise_bitcount(2 * ixtab2[decimation_mode]->num_weights, + (quantization_method) bsd->block_modes[i].quantization_mode); + int bitcount = free_bits_for_partition_count[partition_count] - bits_used_by_weights; + if (bitcount <= 0 || bits_used_by_weights < 24 || bits_used_by_weights > 96) + { + qwt_errors[i] = 1e38f; + continue; + } + qwt_bitcounts[i] = bitcount; + + + // then, generate the optimized set of weights for the mode. + compute_ideal_quantized_weights_for_decimation_table(&(eix1[decimation_mode]), + ixtab2[decimation_mode], + weight_low_value1[i], + weight_high_value1[i], + decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * decimation_mode), + flt_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * i), + u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * i), bsd->block_modes[i].quantization_mode); + compute_ideal_quantized_weights_for_decimation_table(&(eix2[decimation_mode]), + ixtab2[decimation_mode], + weight_low_value2[i], + weight_high_value2[i], + decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * decimation_mode + 1), + flt_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * i + 1), + u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * i + 1), bsd->block_modes[i].quantization_mode); + + + // then, compute quantization errors for the block mode. + qwt_errors[i] = + compute_error_of_weight_set(&(eix1[decimation_mode]), + ixtab2[decimation_mode], + flt_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * i)) + + compute_error_of_weight_set(&(eix2[decimation_mode]), ixtab2[decimation_mode], flt_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * i + 1)); + } + + + // decide the optimal combination of color endpoint encodings and weight encoodings. + int partition_format_specifiers[4][4]; + int quantized_weight[4]; + int color_quantization_level[4]; + int color_quantization_level_mod[4]; + + endpoints epm; + merge_endpoints(&(ei1->ep), &(ei2->ep), separate_component, &epm); + + determine_optimal_set_of_endpoint_formats_to_use(xdim, ydim, zdim, + pi, + blk, + ewb, + &epm, separate_component, qwt_bitcounts, qwt_errors, partition_format_specifiers, quantized_weight, color_quantization_level, color_quantization_level_mod); + + for (i = 0; i < 4; i++) + { + if (quantized_weight[i] < 0) + { + scb->error_block = 1; + scb++; + continue; + } + + uint8_t *u8_weight1_src; + uint8_t *u8_weight2_src; + int weights_to_copy; + + int decimation_mode = bsd->block_modes[quantized_weight[i]].decimation_mode; + int weight_quantization_mode = bsd->block_modes[quantized_weight[i]].quantization_mode; + const decimation_table *it = ixtab2[decimation_mode]; + + u8_weight1_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * quantized_weight[i]); + u8_weight2_src = u8_quantized_decimated_quantized_weights + MAX_WEIGHTS_PER_BLOCK * (2 * quantized_weight[i] + 1); + + + weights_to_copy = it->num_weights; + + // recompute the ideal color endpoints before storing them. + merge_endpoints(&(eix1[decimation_mode].ep), &(eix2[decimation_mode].ep), separate_component, &epm); + + float4 rgbs_colors[4]; + float4 rgbo_colors[4]; + float2 lum_intervals[4]; + + int l; + for (l = 0; l < max_refinement_iters; l++) + { + recompute_ideal_colors(xdim, ydim, zdim, weight_quantization_mode, &epm, rgbs_colors, rgbo_colors, lum_intervals, u8_weight1_src, u8_weight2_src, separate_component, pi, it, blk, ewb); + + // store the colors for the block + for (j = 0; j < partition_count; j++) + { + scb->color_formats[j] = pack_color_endpoints(decode_mode, + epm.endpt0[j], + epm.endpt1[j], + rgbs_colors[j], rgbo_colors[j], lum_intervals[j], partition_format_specifiers[i][j], scb->color_values[j], color_quantization_level[i]); + } + scb->color_formats_matched = 0; + + if ((partition_count >= 2 && scb->color_formats[0] == scb->color_formats[1] + && color_quantization_level != color_quantization_level_mod) + && (partition_count == 2 || (scb->color_formats[0] == scb->color_formats[2] && (partition_count == 3 || (scb->color_formats[0] == scb->color_formats[3]))))) + { + int colorvals[4][12]; + int color_formats_mod[4]; + for (j = 0; j < partition_count; j++) + { + color_formats_mod[j] = pack_color_endpoints(decode_mode, + epm.endpt0[j], + epm.endpt1[j], + rgbs_colors[j], rgbo_colors[j], lum_intervals[j], partition_format_specifiers[i][j], colorvals[j], color_quantization_level_mod[i]); + } + if (color_formats_mod[0] == color_formats_mod[1] + && (partition_count == 2 || (color_formats_mod[0] == color_formats_mod[2] && (partition_count == 3 || (color_formats_mod[0] == color_formats_mod[3]))))) + { + scb->color_formats_matched = 1; + for (j = 0; j < 4; j++) + for (k = 0; k < 12; k++) + scb->color_values[j][k] = colorvals[j][k]; + for (j = 0; j < 4; j++) + scb->color_formats[j] = color_formats_mod[j]; + } + } + + + // store header fields + scb->partition_count = partition_count; + scb->partition_index = partition_index; + scb->color_quantization_level = scb->color_formats_matched ? color_quantization_level_mod[i] : color_quantization_level[i]; + scb->block_mode = quantized_weight[i]; + scb->plane2_color_component = separate_component; + scb->error_block = 0; + + if (scb->color_quantization_level < 4) + { + scb->error_block = 1; // should never happen, but cannot prove it impossible + } + + int adjustments = realign_weights(decode_mode, + xdim, ydim, zdim, + blk, ewb, scb, + u8_weight1_src, + u8_weight2_src); + + if (adjustments == 0) + break; + } + + for (j = 0; j < weights_to_copy; j++) + { + scb->plane1_weights[j] = u8_weight1_src[j]; + scb->plane2_weights[j] = u8_weight2_src[j]; + } + + scb++; + } + +} + + + + + +void expand_block_artifact_suppression(int xdim, int ydim, int zdim, error_weighting_params * ewp) +{ + int x, y, z; + float centerpos_x = (xdim - 1) * 0.5f; + float centerpos_y = (ydim - 1) * 0.5f; + float centerpos_z = (zdim - 1) * 0.5f; + float *bef = ewp->block_artifact_suppression_expanded; + + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + float xdif = (x - centerpos_x) / xdim; + float ydif = (y - centerpos_y) / ydim; + float zdif = (z - centerpos_z) / zdim; + + float wdif = 0.36f; + float dist = sqrt(xdif * xdif + ydif * ydif + zdif * zdif + wdif * wdif); + *bef = pow(dist, ewp->block_artifact_suppression); + bef++; + } +} + + + +// Function to set error weights for each color component for each texel in a block. +// Returns the sum of all the error values set. + +float prepare_error_weight_block(const astc_codec_image * input_image, + int xdim, int ydim, int zdim, const error_weighting_params * ewp, const imageblock * blk, error_weight_block * ewb, error_weight_block_orig * ewbo) +{ + + int x, y, z; + int idx = 0; + + int any_mean_stdev_weight = + ewp->rgb_base_weight != 1.0 || ewp->alpha_base_weight != 1.0 || ewp->rgb_mean_weight != 0.0 || ewp->rgb_stdev_weight != 0.0 || ewp->alpha_mean_weight != 0.0 || ewp->alpha_stdev_weight != 0.0; + + float4 color_weights = float4(ewp->rgba_weights[0], + ewp->rgba_weights[1], + ewp->rgba_weights[2], + ewp->rgba_weights[3]); + + ewb->contains_zeroweight_texels = 0; + + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int xpos = x + blk->xpos; + int ypos = y + blk->ypos; + int zpos = z + blk->zpos; + + if (xpos >= input_image->xsize || ypos >= input_image->ysize || zpos >= input_image->zsize) + { + float4 weights = float4(1e-11f, 1e-11f, 1e-11f, 1e-11f); + ewb->error_weights[idx] = weights; + ewb->contains_zeroweight_texels = 1; + } + else + { + float4 error_weight = float4(ewp->rgb_base_weight, + ewp->rgb_base_weight, + ewp->rgb_base_weight, + ewp->alpha_base_weight); + + if (any_mean_stdev_weight) + { + float4 avg = input_averages[zpos][ypos][xpos]; + if (avg.x < 6e-5f) + avg.x = 6e-5f; + if (avg.y < 6e-5f) + avg.y = 6e-5f; + if (avg.z < 6e-5f) + avg.z = 6e-5f; + if (avg.w < 6e-5f) + avg.w = 6e-5f; + /* + printf("avg: %f %f %f %f\n", avg.x, avg.y, avg.z, avg.w ); */ + avg = avg * avg; + + float4 variance = input_variances[zpos][ypos][xpos]; + variance = variance * variance; + + float favg = (avg.x + avg.y + avg.z) * (1.0f / 3.0f); + float fvar = (variance.x + variance.y + variance.z) * (1.0f / 3.0f); + + float mixing = ewp->rgb_mean_and_stdev_mixing; + avg.xyz = float3(favg, favg, favg) * mixing + avg.xyz * (1.0f - mixing); + variance.xyz = float3(fvar, fvar, fvar) * mixing + variance.xyz * (1.0f - mixing); + + float4 stdev = float4(sqrt(MAX(variance.x, 0.0f)), + sqrt(MAX(variance.y, 0.0f)), + sqrt(MAX(variance.z, 0.0f)), + sqrt(MAX(variance.w, 0.0f))); + + avg.xyz = avg.xyz * ewp->rgb_mean_weight; + avg.w = avg.w * ewp->alpha_mean_weight; + stdev.xyz = stdev.xyz * ewp->rgb_stdev_weight; + stdev.w = stdev.w * ewp->alpha_stdev_weight; + error_weight = error_weight + avg + stdev; + + error_weight = float4(1.0f, 1.0f, 1.0f, 1.0f) / error_weight; + } + + if (ewp->ra_normal_angular_scale) + { + float x = (blk->orig_data[4 * idx] - 0.5f) * 2.0f; + float y = (blk->orig_data[4 * idx + 3] - 0.5f) * 2.0f; + float denom = 1.0f - x * x - y * y; + if (denom < 0.1f) + denom = 0.1f; + denom = 1.0f / denom; + error_weight.x *= 1.0f + x * x * denom; + error_weight.w *= 1.0f + y * y * denom; + } + + if (ewp->enable_rgb_scale_with_alpha) + { + float alpha_scale; + if (ewp->alpha_radius != 0) + alpha_scale = input_alpha_averages[zpos][ypos][xpos]; + else + alpha_scale = blk->orig_data[4 * idx + 3]; + if (alpha_scale < 0.0001f) + alpha_scale = 0.0001f; + alpha_scale *= alpha_scale; + error_weight.xyz = error_weight.xyz * alpha_scale; + } + error_weight = error_weight * color_weights; + error_weight = error_weight * ewp->block_artifact_suppression_expanded[idx]; + + // if we perform a conversion from linear to sRGB, then we multiply + // the weight with the derivative of the linear->sRGB transform function. + if (perform_srgb_transform) + { + float r = blk->orig_data[4 * idx]; + float g = blk->orig_data[4 * idx + 1]; + float b = blk->orig_data[4 * idx + 2]; + if (r < 0.0031308f) + r = 12.92f; + else + r = 0.4396f * pow(r, -0.58333f); + if (g < 0.0031308f) + g = 12.92f; + else + g = 0.4396f * pow(g, -0.58333f); + if (b < 0.0031308f) + b = 12.92f; + else + b = 0.4396f * pow(b, -0.58333f); + error_weight.x *= r; + error_weight.y *= g; + error_weight.z *= b; + } + + /* + printf("%f %f %f %f\n", error_weight.x, error_weight.y, error_weight.z, error_weight.w ); + */ + + // when we loaded the block to begin with, we applied a transfer function + // and computed the derivative of the transfer function. However, the + // error-weight computation so far is based on the original color values, + // not the transfer-function values. As such, we must multiply the + // error weights by the derivative of the inverse of the transfer function, + // which is equivalent to dividing by the derivative of the transfer + // function. + + ewbo->error_weights[idx] = error_weight; + + error_weight.x /= (blk->deriv_data[4 * idx] * blk->deriv_data[4 * idx] * 1e-10f); + error_weight.y /= (blk->deriv_data[4 * idx + 1] * blk->deriv_data[4 * idx + 1] * 1e-10f); + error_weight.z /= (blk->deriv_data[4 * idx + 2] * blk->deriv_data[4 * idx + 2] * 1e-10f); + error_weight.w /= (blk->deriv_data[4 * idx + 3] * blk->deriv_data[4 * idx + 3] * 1e-10f); + + /* + printf("--> %f %f %f %f\n", error_weight.x, error_weight.y, error_weight.z, error_weight.w ); + */ + + ewb->error_weights[idx] = error_weight; + if (dot(error_weight, float4(1, 1, 1, 1)) < 1e-10f) + ewb->contains_zeroweight_texels = 1; + } + idx++; + } + + int i; + + float4 error_weight_sum = float4(0, 0, 0, 0); + int texels_per_block = xdim * ydim * zdim; + + for (i = 0; i < texels_per_block; i++) + { + error_weight_sum = error_weight_sum + ewb->error_weights[i]; + + ewb->texel_weight_r[i] = ewb->error_weights[i].x; + ewb->texel_weight_g[i] = ewb->error_weights[i].y; + ewb->texel_weight_b[i] = ewb->error_weights[i].z; + ewb->texel_weight_a[i] = ewb->error_weights[i].w; + + ewb->texel_weight_rg[i] = (ewb->error_weights[i].x + ewb->error_weights[i].y) * 0.5f; + ewb->texel_weight_rb[i] = (ewb->error_weights[i].x + ewb->error_weights[i].z) * 0.5f; + ewb->texel_weight_gb[i] = (ewb->error_weights[i].y + ewb->error_weights[i].z) * 0.5f; + ewb->texel_weight_ra[i] = (ewb->error_weights[i].x + ewb->error_weights[i].w) * 0.5f; + + ewb->texel_weight_gba[i] = (ewb->error_weights[i].y + ewb->error_weights[i].z + ewb->error_weights[i].w) * 0.333333f; + ewb->texel_weight_rba[i] = (ewb->error_weights[i].x + ewb->error_weights[i].z + ewb->error_weights[i].w) * 0.333333f; + ewb->texel_weight_rga[i] = (ewb->error_weights[i].x + ewb->error_weights[i].y + ewb->error_weights[i].w) * 0.333333f; + ewb->texel_weight_rgb[i] = (ewb->error_weights[i].x + ewb->error_weights[i].y + ewb->error_weights[i].z) * 0.333333f; + ewb->texel_weight[i] = (ewb->error_weights[i].x + ewb->error_weights[i].y + ewb->error_weights[i].z + ewb->error_weights[i].w) * 0.25f; + } + + return dot(error_weight_sum, float4(1, 1, 1, 1)); +} + + +/* + functions to analyze block statistical properties: + * simple properties: * mean * variance + * covariance-matrix correllation coefficients + */ + + +// compute averages and covariance matrices for 4 components +static void compute_covariance_matrix(int xdim, int ydim, int zdim, const imageblock * blk, const error_weight_block * ewb, mat4 * cov_matrix) +{ + int i; + + int texels_per_block = xdim * ydim * zdim; + + float r_sum = 0.0f; + float g_sum = 0.0f; + float b_sum = 0.0f; + float a_sum = 0.0f; + float rr_sum = 0.0f; + float gg_sum = 0.0f; + float bb_sum = 0.0f; + float aa_sum = 0.0f; + float rg_sum = 0.0f; + float rb_sum = 0.0f; + float ra_sum = 0.0f; + float gb_sum = 0.0f; + float ga_sum = 0.0f; + float ba_sum = 0.0f; + + float weight_sum = 0.0f; + + for (i = 0; i < texels_per_block; i++) + { + float weight = ewb->texel_weight[i]; + if (weight < 0.0f) + ASTC_CODEC_INTERNAL_ERROR; + weight_sum += weight; + float r = blk->work_data[4 * i]; + float g = blk->work_data[4 * i + 1]; + float b = blk->work_data[4 * i + 2]; + float a = blk->work_data[4 * i + 3]; + r_sum += r * weight; + rr_sum += r * (r * weight); + rg_sum += g * (r * weight); + rb_sum += b * (r * weight); + ra_sum += a * (r * weight); + g_sum += g * weight; + gg_sum += g * (g * weight); + gb_sum += b * (g * weight); + ga_sum += a * (g * weight); + b_sum += b * weight; + bb_sum += b * (b * weight); + ba_sum += a * (b * weight); + a_sum += a * weight; + aa_sum += a * (a * weight); + } + + float rpt = 1.0f / MAX(weight_sum, 1e-7f); + float rs = r_sum; + float gs = g_sum; + float bs = b_sum; + float as = a_sum; + + cov_matrix->v[0] = float4(rr_sum - rs * rs * rpt, rg_sum - rs * gs * rpt, rb_sum - rs * bs * rpt, ra_sum - rs * as * rpt); + cov_matrix->v[1] = float4(rg_sum - rs * gs * rpt, gg_sum - gs * gs * rpt, gb_sum - gs * bs * rpt, ga_sum - gs * as * rpt); + cov_matrix->v[2] = float4(rb_sum - rs * bs * rpt, gb_sum - gs * bs * rpt, bb_sum - bs * bs * rpt, ba_sum - bs * as * rpt); + cov_matrix->v[3] = float4(ra_sum - rs * as * rpt, ga_sum - gs * as * rpt, ba_sum - bs * as * rpt, aa_sum - as * as * rpt); + +} + + + +void prepare_block_statistics(int xdim, int ydim, int zdim, const imageblock * blk, const error_weight_block * ewb, int *is_normal_map, float *lowest_correl) +{ + int i; + + mat4 cov_matrix; + + compute_covariance_matrix(xdim, ydim, zdim, blk, ewb, &cov_matrix); + + // use the covariance matrix to compute + // correllation coefficients + float rr_var = cov_matrix.v[0].x; + float gg_var = cov_matrix.v[1].y; + float bb_var = cov_matrix.v[2].z; + float aa_var = cov_matrix.v[3].w; + + float rg_correlation = cov_matrix.v[0].y / sqrt(MAX(rr_var * gg_var, 1e-30f)); + float rb_correlation = cov_matrix.v[0].z / sqrt(MAX(rr_var * bb_var, 1e-30f)); + float ra_correlation = cov_matrix.v[0].w / sqrt(MAX(rr_var * aa_var, 1e-30f)); + float gb_correlation = cov_matrix.v[1].z / sqrt(MAX(gg_var * bb_var, 1e-30f)); + float ga_correlation = cov_matrix.v[1].w / sqrt(MAX(gg_var * aa_var, 1e-30f)); + float ba_correlation = cov_matrix.v[2].w / sqrt(MAX(bb_var * aa_var, 1e-30f)); + + if (astc_isnan(rg_correlation)) + rg_correlation = 1.0f; + if (astc_isnan(rb_correlation)) + rb_correlation = 1.0f; + if (astc_isnan(ra_correlation)) + ra_correlation = 1.0f; + if (astc_isnan(gb_correlation)) + gb_correlation = 1.0f; + if (astc_isnan(ga_correlation)) + ga_correlation = 1.0f; + if (astc_isnan(ba_correlation)) + ba_correlation = 1.0f; + + float lowest_correlation = MIN(fabs(rg_correlation), fabs(rb_correlation)); + lowest_correlation = MIN(lowest_correlation, fabs(ra_correlation)); + lowest_correlation = MIN(lowest_correlation, fabs(gb_correlation)); + lowest_correlation = MIN(lowest_correlation, fabs(ga_correlation)); + lowest_correlation = MIN(lowest_correlation, fabs(ba_correlation)); + *lowest_correl = lowest_correlation; + + // compute a "normal-map" factor + // this factor should be exactly 0.0 for a normal map, while it may be all over the + // place for anything that is NOT a normal map. We can probably assume that a factor + // of less than 0.2f represents a normal map. + + float nf_sum = 0.0f; + + int texels_per_block = xdim * ydim * zdim; + + for (i = 0; i < texels_per_block; i++) + { + float3 val = float3(blk->orig_data[4 * i], + blk->orig_data[4 * i + 1], + blk->orig_data[4 * i + 2]); + val = (val - float3(0.5f, 0.5f, 0.5f)) * 2.0f; + float length_squared = dot(val, val); + float nf = fabs(length_squared - 1.0f); + nf_sum += nf; + } + float nf_avg = nf_sum / texels_per_block; + *is_normal_map = nf_avg < 0.2; +} + + + + + +void compress_constant_color_block(int xdim, int ydim, int zdim, const imageblock * blk, const error_weight_block * ewb, symbolic_compressed_block * scb) +{ + int texel_count = xdim * ydim * zdim; + int i; + + float4 color_sum = float4(0, 0, 0, 0); + float4 color_weight_sum = float4(0, 0, 0, 0); + + const float *clp = blk->work_data; + for (i = 0; i < texel_count; i++) + { + float4 weights = ewb->error_weights[i]; + float4 color_data = float4(clp[4 * i], clp[4 * i + 1], clp[4 * i + 2], clp[4 * i + 3]); + color_sum = color_sum + (color_data * weights); + color_weight_sum = color_weight_sum + weights; + } + + float4 avg_color = color_sum / color_weight_sum; + + int use_fp16 = blk->rgb_lns[0]; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Averaged color: %f %f %f %f\n", avg_color.x, avg_color.y, avg_color.z, avg_color.w); + } + #endif + + // convert the color + if (blk->rgb_lns[0]) + { + int avg_red = static_cast < int >(floor(avg_color.x + 0.5f)); + int avg_green = static_cast < int >(floor(avg_color.y + 0.5f)); + int avg_blue = static_cast < int >(floor(avg_color.z + 0.5f)); + + if (avg_red < 0) + avg_red = 0; + else if (avg_red > 65535) + avg_red = 65535; + + if (avg_green < 0) + avg_green = 0; + else if (avg_green > 65535) + avg_green = 65535; + + if (avg_blue < 0) + avg_blue = 0; + else if (avg_blue > 65535) + avg_blue = 65535; + + avg_color.x = sf16_to_float(lns_to_sf16(avg_red)); + avg_color.y = sf16_to_float(lns_to_sf16(avg_green)); + avg_color.z = sf16_to_float(lns_to_sf16(avg_blue)); + } + else + { + avg_color.x *= (1.0f / 65535.0f); + avg_color.y *= (1.0f / 65535.0f); + avg_color.z *= (1.0f / 65535.0f); + } + if (blk->alpha_lns[0]) + { + int avg_alpha = static_cast < int >(floor(avg_color.w + 0.5f)); + + if (avg_alpha < 0) + avg_alpha = 0; + else if (avg_alpha > 65535) + avg_alpha = 65535; + + avg_color.w = sf16_to_float(lns_to_sf16(avg_alpha)); + } + else + { + avg_color.w *= (1.0f / 65535.0f); + } + +#ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Averaged color: %f %f %f %f (%d)\n", avg_color.x, avg_color.y, avg_color.z, avg_color.w, use_fp16); + + } +#endif + + if (use_fp16) + { + scb->error_block = 0; + scb->block_mode = -1; + scb->partition_count = 0; + scb->constant_color[0] = float_to_sf16(avg_color.x, SF_NEARESTEVEN); + scb->constant_color[1] = float_to_sf16(avg_color.y, SF_NEARESTEVEN); + scb->constant_color[2] = float_to_sf16(avg_color.z, SF_NEARESTEVEN); + scb->constant_color[3] = float_to_sf16(avg_color.w, SF_NEARESTEVEN); + } + + else + { + scb->error_block = 0; + scb->block_mode = -2; + scb->partition_count = 0; + float red = avg_color.x; + float green = avg_color.y; + float blue = avg_color.z; + float alpha = avg_color.w; + if (red < 0) + red = 0; + else if (red > 1) + red = 1; + if (green < 0) + green = 0; + else if (green > 1) + green = 1; + if (blue < 0) + blue = 0; + else if (blue > 1) + blue = 1; + if (alpha < 0) + alpha = 0; + else if (alpha > 1) + alpha = 1; + scb->constant_color[0] = static_cast < int >(floor(red * 65535.0f + 0.5f)); + scb->constant_color[1] = static_cast < int >(floor(green * 65535.0f + 0.5f)); + scb->constant_color[2] = static_cast < int >(floor(blue * 65535.0f + 0.5f)); + scb->constant_color[3] = static_cast < int >(floor(alpha * 65535.0f + 0.5f)); + } +} + +int block_mode_histogram[2048]; + +float compress_symbolic_block(const astc_codec_image * input_image, + astc_decode_mode decode_mode, int xdim, int ydim, int zdim, const error_weighting_params * ewp, const imageblock * blk, symbolic_compressed_block * scb, + compress_symbolic_block_buffers * tmpbuf) +{ + int i, j; + int xpos = blk->xpos; + int ypos = blk->ypos; + int zpos = blk->zpos; + + int x, y, z; + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Diagnostics of block of dimension %d x %d x %d\n\n", xdim, ydim, zdim); + + printf("XPos: %d YPos: %d ZPos: %d\n", xpos, ypos, zpos); + + printf("Red-min: %f Red-max: %f\n", blk->red_min, blk->red_max); + printf("Green-min: %f Green-max: %f\n", blk->green_min, blk->green_max); + printf("Blue-min: %f Blue-max: %f\n", blk->blue_min, blk->blue_max); + printf("Alpha-min: %f Alpha-max: %f\n", blk->alpha_min, blk->alpha_max); + printf("Grayscale: %d\n", blk->grayscale); + + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int idx = ((z * ydim + y) * xdim + x) * 4; + printf("Texel (%d %d %d) : orig=< %g, %g, %g, %g >, work=< %g, %g, %g, %g >\n", + x, y, z, + blk->orig_data[idx], + blk->orig_data[idx + 1], blk->orig_data[idx + 2], blk->orig_data[idx + 3], blk->work_data[idx], blk->work_data[idx + 1], blk->work_data[idx + 2], blk->work_data[idx + 3]); + } + printf("\n"); + } + #endif + + + if (blk->red_min == blk->red_max && blk->green_min == blk->green_max && blk->blue_min == blk->blue_max && blk->alpha_min == blk->alpha_max) + { + + // detected a constant-color block. Encode as FP16 if using HDR + scb->error_block = 0; + + if (rgb_force_use_of_hdr) + { + scb->block_mode = -1; + scb->partition_count = 0; + scb->constant_color[0] = float_to_sf16(blk->orig_data[0], SF_NEARESTEVEN); + scb->constant_color[1] = float_to_sf16(blk->orig_data[1], SF_NEARESTEVEN); + scb->constant_color[2] = float_to_sf16(blk->orig_data[2], SF_NEARESTEVEN); + scb->constant_color[3] = float_to_sf16(blk->orig_data[3], SF_NEARESTEVEN); + } + else + { + // Encode as UNORM16 if NOT using HDR. + scb->block_mode = -2; + scb->partition_count = 0; + float red = blk->orig_data[0]; + float green = blk->orig_data[1]; + float blue = blk->orig_data[2]; + float alpha = blk->orig_data[3]; + if (red < 0) + red = 0; + else if (red > 1) + red = 1; + if (green < 0) + green = 0; + else if (green > 1) + green = 1; + if (blue < 0) + blue = 0; + else if (blue > 1) + blue = 1; + if (alpha < 0) + alpha = 0; + else if (alpha > 1) + alpha = 1; + scb->constant_color[0] = (int)floor(red * 65535.0f + 0.5f); + scb->constant_color[1] = (int)floor(green * 65535.0f + 0.5f); + scb->constant_color[2] = (int)floor(blue * 65535.0f + 0.5f); + scb->constant_color[3] = (int)floor(alpha * 65535.0f + 0.5f); + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Block is single-color <%4.4X %4.4X %4.4X %4.4X>\n", scb->constant_color[0], scb->constant_color[1], scb->constant_color[2], scb->constant_color[3]); + } + #endif + + if (print_tile_errors) + printf("0\n"); + + physical_compressed_block psb = symbolic_to_physical(xdim, ydim, zdim, scb); + physical_to_symbolic(xdim, ydim, zdim, psb, scb); + + return 0.0f; + } + + error_weight_block *ewb = tmpbuf->ewb; + error_weight_block_orig *ewbo = tmpbuf->ewbo; + + float error_weight_sum = prepare_error_weight_block(input_image, + xdim, ydim, zdim, + ewp, blk, ewb, ewbo); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("\n"); + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int idx = (z * ydim + y) * xdim + x; + printf("ErrorWeight (%d %d %d) : < %g, %g, %g, %g >\n", x, y, z, ewb->error_weights[idx].x, ewb->error_weights[idx].y, ewb->error_weights[idx].z, ewb->error_weights[idx].w); + } + printf("\n"); + } + #endif + + symbolic_compressed_block *tempblocks = tmpbuf->tempblocks; + + float error_of_best_block = 1e20f; + // int modesel=0; + + imageblock *temp = tmpbuf->temp; + + float best_errorvals_in_modes[17]; + for (i = 0; i < 17; i++) + best_errorvals_in_modes[i] = 1e30f; + + int uses_alpha = imageblock_uses_alpha(xdim, ydim, zdim, blk); + + + // compression of average-color blocks disabled for the time being; + // they produce extremely severe block artifacts. +#if 0 + // first, compress an averaged-color block + compress_constant_color_block(xdim, ydim, zdim, blk, ewb, scb); + + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, xpos, ypos, zpos, scb, temp); + + float avgblock_errorval = compute_imageblock_difference(xdim, ydim, zdim, + blk, temp, ewb) * 4.0f; // bias somewhat against the average-color block. + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("\n-----------------------------------\n"); + printf("Average-color block test completed\n"); + printf("Resulting error value: %g\n", avgblock_errorval); + } + #endif + + + if (avgblock_errorval < error_of_best_block) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Accepted as better than previous-best-error, which was %g\n", error_of_best_block); + #endif + + error_of_best_block = avgblock_errorval; + // *scb = tempblocks[j]; + modesel = 0; + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("-----------------------------------\n"); + } + #endif +#endif + + + float mode_cutoff = ewp->block_mode_cutoff; + + // next, test mode #0. This mode uses 1 plane of weights and 1 partition. + // we test it twice, first with a modecutoff of 0, then with the specified mode-cutoff. + // This causes an early-out that speeds up encoding of "easy" content. + + float modecutoffs[2]; + float errorval_mult[2] = { 2.5, 1 }; + modecutoffs[0] = 0; + modecutoffs[1] = mode_cutoff; + + #if 0 + if ((error_of_best_block / error_weight_sum) < ewp->texel_avg_error_limit) + goto END_OF_TESTS; + #endif + + float best_errorval_in_mode; + for (i = 0; i < 2; i++) + { + compress_symbolic_block_fixed_partition_1_plane(decode_mode, modecutoffs[i], ewp->max_refinement_iters, xdim, ydim, zdim, 1, // partition count + 0, // partition index + blk, ewb, tempblocks, tmpbuf->plane1); + + best_errorval_in_mode = 1e30f; + for (j = 0; j < 4; j++) + { + if (tempblocks[j].error_block) + continue; + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, xpos, ypos, zpos, tempblocks + j, temp); + float errorval = compute_imageblock_difference(xdim, ydim, zdim, + blk, temp, ewb) * errorval_mult[i]; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("\n-----------------------------------\n"); + printf("Single-weight partition test 0 (1 partition) completed\n"); + printf("Resulting error value: %g\n", errorval); + } + #endif + + if (errorval < best_errorval_in_mode) + best_errorval_in_mode = errorval; + + if (errorval < error_of_best_block) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Accepted as better than previous-best-error, which was %g\n", error_of_best_block); + #endif + + error_of_best_block = errorval; + *scb = tempblocks[j]; + + // modesel = 0; + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("-----------------------------------\n"); + } + #endif + } + + best_errorvals_in_modes[0] = best_errorval_in_mode; + if ((error_of_best_block / error_weight_sum) < ewp->texel_avg_error_limit) + goto END_OF_TESTS; + } + + int is_normal_map; + float lowest_correl; + prepare_block_statistics(xdim, ydim, zdim, blk, ewb, &is_normal_map, &lowest_correl); + + if (is_normal_map && lowest_correl < 0.99f) + lowest_correl = 0.99f; + + // next, test the four possible 1-partition, 2-planes modes + for (i = 0; i < 4; i++) + { + + if (lowest_correl > ewp->lowest_correlation_cutoff) + continue; + + if (blk->grayscale && i != 3) + continue; + + if (!uses_alpha && i == 3) + continue; + + compress_symbolic_block_fixed_partition_2_planes(decode_mode, mode_cutoff, ewp->max_refinement_iters, xdim, ydim, zdim, 1, // partition count + 0, // partition index + i, // the color component to test a separate plane of weights for. + blk, ewb, tempblocks, tmpbuf->planes2); + + best_errorval_in_mode = 1e30f; + for (j = 0; j < 4; j++) + { + if (tempblocks[j].error_block) + continue; + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, xpos, ypos, zpos, tempblocks + j, temp); + float errorval = compute_imageblock_difference(xdim, ydim, zdim, + blk, temp, ewb); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("\n-----------------------------------\n"); + printf("Dual-weight partition test %d (1 partition) completed\n", i); + printf("Resulting error value: %g\n", errorval); + } + #endif + + if (errorval < best_errorval_in_mode) + best_errorval_in_mode = errorval; + + if (errorval < error_of_best_block) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Accepted as better than previous-best-error, which was %g\n", error_of_best_block); + #endif + + error_of_best_block = errorval; + *scb = tempblocks[j]; + + // modesel = i+1; + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("-----------------------------------\n"); + } + #endif + + best_errorvals_in_modes[i + 1] = best_errorval_in_mode; + } + + if ((error_of_best_block / error_weight_sum) < ewp->texel_avg_error_limit) + goto END_OF_TESTS; + } + + // find best blocks for 2, 3 and 4 partitions + int partition_count; + for (partition_count = 2; partition_count <= 4; partition_count++) + { + int partition_indices_1plane[2]; + int partition_indices_2planes[2]; + + find_best_partitionings(ewp->partition_search_limit, + xdim, ydim, zdim, partition_count, blk, ewb, 1, + &(partition_indices_1plane[0]), &(partition_indices_1plane[1]), &(partition_indices_2planes[0])); + + for (i = 0; i < 2; i++) + { + compress_symbolic_block_fixed_partition_1_plane(decode_mode, mode_cutoff, ewp->max_refinement_iters, xdim, ydim, zdim, partition_count, partition_indices_1plane[i], blk, ewb, tempblocks, tmpbuf->plane1); + + best_errorval_in_mode = 1e30f; + for (j = 0; j < 4; j++) + { + if (tempblocks[j].error_block) + continue; + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, xpos, ypos, zpos, tempblocks + j, temp); + float errorval = compute_imageblock_difference(xdim, ydim, zdim, + blk, temp, ewb); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("\n-----------------------------------\n"); + printf("Single-weight partition test %d (%d partitions) completed\n", i, partition_count); + printf("Resulting error value: %g\n", errorval); + } + #endif + + if (errorval < best_errorval_in_mode) + best_errorval_in_mode = errorval; + + if (errorval < error_of_best_block) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Accepted as better than previous-best-error, which was %g\n", error_of_best_block); + #endif + + error_of_best_block = errorval; + *scb = tempblocks[j]; + + // modesel = 4*(partition_count-2) + 5 + i; + } + } + + best_errorvals_in_modes[4 * (partition_count - 2) + 5 + i] = best_errorval_in_mode; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("-----------------------------------\n"); + } + #endif + + if ((error_of_best_block / error_weight_sum) < ewp->texel_avg_error_limit) + goto END_OF_TESTS; + } + + + if (partition_count == 2 && !is_normal_map && MIN(best_errorvals_in_modes[5], best_errorvals_in_modes[6]) > (best_errorvals_in_modes[0] * ewp->partition_1_to_2_limit)) + goto END_OF_TESTS; + + // don't bother to check 4 partitions for dual plane of weightss, ever. + if (partition_count == 4) + break; + + for (i = 0; i < 2; i++) + { + if (lowest_correl > ewp->lowest_correlation_cutoff) + continue; + compress_symbolic_block_fixed_partition_2_planes(decode_mode, + mode_cutoff, + ewp->max_refinement_iters, + xdim, ydim, zdim, + partition_count, + partition_indices_2planes[i] & (PARTITION_COUNT - 1), partition_indices_2planes[i] >> PARTITION_BITS, + blk, ewb, tempblocks, tmpbuf->planes2); + + best_errorval_in_mode = 1e30f; + for (j = 0; j < 4; j++) + { + if (tempblocks[j].error_block) + continue; + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, xpos, ypos, zpos, tempblocks + j, temp); + + float errorval = compute_imageblock_difference(xdim, ydim, zdim, + blk, temp, ewb); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("\n-----------------------------------\n"); + printf("Dual-weight partition test %d (%d partitions) completed\n", i, partition_count); + printf("Resulting error value: %g\n", errorval); + } + #endif + + if (errorval < best_errorval_in_mode) + best_errorval_in_mode = errorval; + + if (errorval < error_of_best_block) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Accepted as better than previous-best-error, which was %g\n", error_of_best_block); + #endif + + error_of_best_block = errorval; + *scb = tempblocks[j]; + + // modesel = 4*(partition_count-2) + 5 + 2 + i; + } + } + + best_errorvals_in_modes[4 * (partition_count - 2) + 5 + 2 + i] = best_errorval_in_mode; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("-----------------------------------\n"); + } + #endif + + if ((error_of_best_block / error_weight_sum) < ewp->texel_avg_error_limit) + goto END_OF_TESTS; + } + } + + END_OF_TESTS: + + #if 0 + if (print_statistics) + { + for (i = 0; i < 13; i++) + printf("%f ", best_errorvals_in_modes[i]); + + printf("%d %f %f %f ", modesel, error_of_best_block, + MIN(best_errorvals_in_modes[1], best_errorvals_in_modes[2]) / best_errorvals_in_modes[0], + MIN(MIN(best_errorvals_in_modes[7], best_errorvals_in_modes[8]), best_errorvals_in_modes[9]) / best_errorvals_in_modes[0]); + + printf("\n"); + } + #endif + + if (scb->block_mode >= 0) + block_mode_histogram[scb->block_mode & 0x7ff]++; + + + // compress/decompress to a physical block + physical_compressed_block psb = symbolic_to_physical(xdim, ydim, zdim, scb); + physical_to_symbolic(xdim, ydim, zdim, psb, scb); + + + if (print_tile_errors) + printf("%g\n", error_of_best_block); + + + // mean squared error per color component. + return error_of_best_block / ((float)xdim * ydim * zdim); +} diff --git a/third_party/astcenc/Source/astc_compute_variance.cpp b/third_party/astcenc/Source/astc_compute_variance.cpp new file mode 100644 index 0000000000..782bd1dd02 --- /dev/null +++ b/third_party/astcenc/Source/astc_compute_variance.cpp @@ -0,0 +1,524 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief ASTC functions to calculate, for each pixel and each color component, + * its variance within an NxN footprint; we want N to be parametric. + * + * The routine below uses summed area tables in order to perform the + * computation in O(1) time per pixel, independent of big N is. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include +#include "mathlib.h" +#include "softfloat.h" + +float4 *** input_averages; +float *** input_alpha_averages; +float4 *** input_variances; + +#include + +// routine to compute averages and variances 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. + +static void compute_pixel_region_variance(const astc_codec_image * img, float rgb_power_to_use, float alpha_power_to_use, swizzlepattern swz, int use_z_axis, + int source_xoffset,int source_yoffset, int source_zoffset, // position of upper-left pixel in data set + int xsize, int ysize, int zsize, // the size of the region to actually compute averages and variances for. + int avg_var_kernel_radius, int alpha_kernel_radius, + int dest_xoffset, int dest_yoffset, int dest_zoffset) +{ + int x, y, z; + + int kernel_radius = MAX(avg_var_kernel_radius, alpha_kernel_radius); + int kerneldim = 2 * kernel_radius + 1; + + // allocate memory + int xpadsize = xsize + kerneldim; + int ypadsize = ysize + kerneldim; + int zpadsize = zsize + (use_z_axis ? kerneldim : 1); + + double4 ***varbuf1 = new double4 **[zpadsize]; + double4 ***varbuf2 = new double4 **[zpadsize]; + varbuf1[0] = new double4 *[ypadsize * zpadsize]; + varbuf2[0] = new double4 *[ypadsize * zpadsize]; + varbuf1[0][0] = new double4[xpadsize * ypadsize * zpadsize]; + varbuf2[0][0] = new double4[xpadsize * ypadsize * zpadsize]; + + + for (z = 1; z < zpadsize; z++) + { + varbuf1[z] = varbuf1[0] + ypadsize * z; + varbuf2[z] = varbuf2[0] + ypadsize * z; + varbuf1[z][0] = varbuf1[0][0] + xpadsize * ypadsize * z; + varbuf2[z][0] = varbuf2[0][0] + xpadsize * ypadsize * z; + } + + for (z = 0; z < zpadsize; z++) + for (y = 1; y < ypadsize; y++) + { + varbuf1[z][y] = varbuf1[z][0] + xpadsize * y; + varbuf2[z][y] = varbuf2[z][0] + xpadsize * y; + } + + int powers_are_1 = (rgb_power_to_use == 1.0f) && (alpha_power_to_use == 1.0f); + + + // load x and x^2 values into the allocated buffers + if (img->imagedata8) + { + uint8_t data[6]; + data[4] = 0; + data[5] = 255; + + for (z = 0; z < zpadsize - 1; z++) + { + int z_src = z + source_zoffset - (use_z_axis ? kernel_radius : 0); + for (y = 0; y < ypadsize - 1; y++) + { + int y_src = y + source_yoffset - kernel_radius; + for (x = 0; x < xpadsize - 1; x++) + { + int x_src = x + source_xoffset - kernel_radius; + data[0] = img->imagedata8[z_src][y_src][4 * x_src + 0]; + data[1] = img->imagedata8[z_src][y_src][4 * x_src + 1]; + data[2] = img->imagedata8[z_src][y_src][4 * x_src + 2]; + data[3] = img->imagedata8[z_src][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]; + + double4 d = double4(r * (1.0 / 255.0), + g * (1.0 / 255.0), + b * (1.0 / 255.0), + a * (1.0 / 255.0)); + + if (perform_srgb_transform) + { + d.x = (d.x <= 0.04045) ? d.x * (1.0 / 12.92) : (d.x <= 1) ? pow((d.x + 0.055) * (1.0 / 1.055), 2.4) : d.x; + d.y = (d.y <= 0.04045) ? d.y * (1.0 / 12.92) : (d.y <= 1) ? pow((d.y + 0.055) * (1.0 / 1.055), 2.4) : d.y; + d.z = (d.z <= 0.04045) ? d.z * (1.0 / 12.92) : (d.z <= 1) ? pow((d.z + 0.055) * (1.0 / 1.055), 2.4) : d.z; + } + + if (!powers_are_1) + { + d.x = pow(MAX(d.x, 1e-6), (double)rgb_power_to_use); + d.y = pow(MAX(d.y, 1e-6), (double)rgb_power_to_use); + d.z = pow(MAX(d.z, 1e-6), (double)rgb_power_to_use); + d.w = pow(MAX(d.w, 1e-6), (double)alpha_power_to_use); + } + + varbuf1[z][y][x] = d; + varbuf2[z][y][x] = d * d; + } + } + } + } + else + { + uint16_t data[6]; + data[4] = 0; + data[5] = 0x3C00; // 1.0 encoded as FP16. + + for (z = 0; z < zpadsize - 1; z++) + { + int z_src = z + source_zoffset - (use_z_axis ? kernel_radius : 0); + for (y = 0; y < ypadsize - 1; y++) + { + int y_src = y + source_yoffset - kernel_radius; + for (x = 0; x < xpadsize - 1; x++) + { + int x_src = x + source_xoffset - kernel_radius; + data[0] = img->imagedata16[z_src][y_src][4 * x_src]; + data[1] = img->imagedata16[z_src][y_src][4 * x_src + 1]; + data[2] = img->imagedata16[z_src][y_src][4 * x_src + 2]; + data[3] = img->imagedata16[z_src][y_src][4 * x_src + 3]; + + uint16_t r = data[swz.r]; + uint16_t g = data[swz.g]; + uint16_t b = data[swz.b]; + uint16_t a = data[swz.a]; + + double4 d = double4(sf16_to_float(r), + sf16_to_float(g), + sf16_to_float(b), + sf16_to_float(a)); + + if (perform_srgb_transform) + { + d.x = (d.x <= 0.04045) ? d.x * (1.0 / 12.92) : (d.x <= 1) ? pow((d.x + 0.055) * (1.0 / 1.055), 2.4) : d.x; + d.y = (d.y <= 0.04045) ? d.y * (1.0 / 12.92) : (d.y <= 1) ? pow((d.y + 0.055) * (1.0 / 1.055), 2.4) : d.y; + d.z = (d.z <= 0.04045) ? d.z * (1.0 / 12.92) : (d.z <= 1) ? pow((d.z + 0.055) * (1.0 / 1.055), 2.4) : d.z; + } + + if (!powers_are_1) + { + d.x = pow(MAX(d.x, 1e-6), (double)rgb_power_to_use); + d.y = pow(MAX(d.y, 1e-6), (double)rgb_power_to_use); + d.z = pow(MAX(d.z, 1e-6), (double)rgb_power_to_use); + d.w = pow(MAX(d.w, 1e-6), (double)alpha_power_to_use); + } + + varbuf1[z][y][x] = d; + varbuf2[z][y][x] = d * d; + } + } + } + } + + + + // pad out buffers with 0s + for (z = 0; z < zpadsize; z++) + { + for (y = 0; y < ypadsize; y++) + { + varbuf1[z][y][xpadsize - 1] = double4(0.0, 0.0, 0.0, 0.0); + varbuf2[z][y][xpadsize - 1] = double4(0.0, 0.0, 0.0, 0.0); + } + for (x = 0; x < xpadsize; x++) + { + varbuf1[z][ypadsize - 1][x] = double4(0.0, 0.0, 0.0, 0.0); + varbuf2[z][ypadsize - 1][x] = double4(0.0, 0.0, 0.0, 0.0); + } + } + + if (use_z_axis) + for (y = 0; y < ypadsize; y++) + for (x = 0; x < xpadsize; x++) + { + varbuf1[zpadsize - 1][y][x] = double4(0.0, 0.0, 0.0, 0.0); + varbuf2[zpadsize - 1][y][x] = double4(0.0, 0.0, 0.0, 0.0); + } + + + // generate summed-area tables for x and x2; this is done in-place + for (z = 0; z < zpadsize; z++) + for (y = 0; y < ypadsize; y++) + { + double4 summa1 = double4(0.0, 0.0, 0.0, 0.0); + double4 summa2 = double4(0.0, 0.0, 0.0, 0.0); + for (x = 0; x < xpadsize; x++) + { + double4 val1 = varbuf1[z][y][x]; + double4 val2 = varbuf2[z][y][x]; + varbuf1[z][y][x] = summa1; + varbuf2[z][y][x] = summa2; + summa1 = summa1 + val1; + summa2 = summa2 + val2; + } + } + + for (z = 0; z < zpadsize; z++) + for (x = 0; x < xpadsize; x++) + { + double4 summa1 = double4(0.0, 0.0, 0.0, 0.0); + double4 summa2 = double4(0.0, 0.0, 0.0, 0.0); + for (y = 0; y < ypadsize; y++) + { + double4 val1 = varbuf1[z][y][x]; + double4 val2 = varbuf2[z][y][x]; + varbuf1[z][y][x] = summa1; + varbuf2[z][y][x] = summa2; + summa1 = summa1 + val1; + summa2 = summa2 + val2; + } + } + + if (use_z_axis) + for (y = 0; y < ypadsize; y++) + for (x = 0; x < xpadsize; x++) + { + double4 summa1 = double4(0.0, 0.0, 0.0, 0.0); + double4 summa2 = double4(0.0, 0.0, 0.0, 0.0); + for (z = 0; z < zpadsize; z++) + { + double4 val1 = varbuf1[z][y][x]; + double4 val2 = varbuf2[z][y][x]; + varbuf1[z][y][x] = summa1; + varbuf2[z][y][x] = summa2; + summa1 = summa1 + val1; + summa2 = summa2 + val2; + } + } + + + int avg_var_kerneldim = 2 * avg_var_kernel_radius + 1; + int alpha_kerneldim = 2 * alpha_kernel_radius + 1; + + + // compute a few constants used in the variance-calculation. + double avg_var_samples; + double alpha_rsamples; + double mul1; + + if (use_z_axis) + { + avg_var_samples = avg_var_kerneldim * avg_var_kerneldim * avg_var_kerneldim; + alpha_rsamples = 1.0 / (alpha_kerneldim * alpha_kerneldim * alpha_kerneldim); + } + else + { + avg_var_samples = avg_var_kerneldim * avg_var_kerneldim; + alpha_rsamples = 1.0 / (alpha_kerneldim * alpha_kerneldim); + } + + + double avg_var_rsamples = 1.0 / avg_var_samples; + if (avg_var_samples == 1) + mul1 = 1.0; + else + mul1 = 1.0 / (avg_var_samples * (avg_var_samples - 1)); + + + double mul2 = avg_var_samples * mul1; + + + // use the summed-area tables to compute variance for each sample-neighborhood + if (use_z_axis) + { + for (z = 0; z < zsize; z++) + { + int z_src = z + kernel_radius; + int z_dst = z + dest_zoffset; + for (y = 0; y < ysize; y++) + { + int y_src = y + kernel_radius; + int y_dst = y + dest_yoffset; + + for (x = 0; x < xsize; x++) + { + int x_src = x + kernel_radius; + int x_dst = x + dest_xoffset; + + // summed-area table lookups for alpha average + double vasum = + (varbuf1[z_src + 1][y_src - alpha_kernel_radius][x_src - alpha_kernel_radius].w + - varbuf1[z_src + 1][y_src - alpha_kernel_radius][x_src + alpha_kernel_radius + 1].w + - varbuf1[z_src + 1][y_src + alpha_kernel_radius + 1][x_src - alpha_kernel_radius].w + + varbuf1[z_src + 1][y_src + alpha_kernel_radius + 1][x_src + alpha_kernel_radius + 1].w) - + (varbuf1[z_src][y_src - alpha_kernel_radius][x_src - alpha_kernel_radius].w + - varbuf1[z_src][y_src - alpha_kernel_radius][x_src + alpha_kernel_radius + 1].w + - varbuf1[z_src][y_src + alpha_kernel_radius + 1][x_src - alpha_kernel_radius].w + varbuf1[z_src][y_src + alpha_kernel_radius + 1][x_src + alpha_kernel_radius + 1].w); + input_alpha_averages[z_dst][y_dst][x_dst] = static_cast < float >(vasum * alpha_rsamples); + + + // summed-area table lookups for RGBA average + double4 v0sum = + (varbuf1[z_src + 1][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf1[z_src + 1][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf1[z_src + 1][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + + varbuf1[z_src + 1][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]) - + (varbuf1[z_src][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf1[z_src][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]); + + double4 avg = v0sum * avg_var_rsamples; + + float4 favg = float4(static_cast < float >(avg.x), + static_cast < float >(avg.y), + static_cast < float >(avg.z), + static_cast < float >(avg.w)); + input_averages[z_dst][y_dst][x_dst] = favg; + + + // summed-area table lookups for variance + double4 v1sum = + (varbuf1[z_src + 1][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf1[z_src + 1][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf1[z_src + 1][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + + varbuf1[z_src + 1][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]) - + (varbuf1[z_src][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf1[z_src][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]); + double4 v2sum = + (varbuf2[z_src + 1][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf2[z_src + 1][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf2[z_src + 1][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + + varbuf2[z_src + 1][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]) - + (varbuf2[z_src][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf2[z_src][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf2[z_src][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + varbuf2[z_src][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]); + + // the actual variance + double4 variance = mul2 * v2sum - mul1 * (v1sum * v1sum); + + float4 fvar = float4(static_cast < float >(variance.x), + static_cast < float >(variance.y), + static_cast < float >(variance.z), + static_cast < float >(variance.w)); + input_variances[z_dst][y_dst][x_dst] = fvar; + } + } + } + } + else + { + for (z = 0; z < zsize; z++) + { + int z_src = z; + int z_dst = z + dest_zoffset; + for (y = 0; y < ysize; y++) + { + int y_src = y + kernel_radius; + int y_dst = y + dest_yoffset; + + for (x = 0; x < xsize; x++) + { + int x_src = x + kernel_radius; + int x_dst = x + dest_xoffset; + + // summed-area table lookups for alpha average + double vasum = + varbuf1[z_src][y_src - alpha_kernel_radius][x_src - alpha_kernel_radius].w + - varbuf1[z_src][y_src - alpha_kernel_radius][x_src + alpha_kernel_radius + 1].w + - varbuf1[z_src][y_src + alpha_kernel_radius + 1][x_src - alpha_kernel_radius].w + varbuf1[z_src][y_src + alpha_kernel_radius + 1][x_src + alpha_kernel_radius + 1].w; + input_alpha_averages[z_dst][y_dst][x_dst] = static_cast < float >(vasum * alpha_rsamples); + + + // summed-area table lookups for RGBA average + double4 v0sum = + varbuf1[z_src][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf1[z_src][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]; + + double4 avg = v0sum * avg_var_rsamples; + + float4 favg = float4(static_cast < float >(avg.x), + static_cast < float >(avg.y), + static_cast < float >(avg.z), + static_cast < float >(avg.w)); + input_averages[z_dst][y_dst][x_dst] = favg; + + + // summed-area table lookups for variance + double4 v1sum = + varbuf1[z_src][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf1[z_src][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + varbuf1[z_src][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]; + double4 v2sum = + varbuf2[z_src][y_src - avg_var_kernel_radius][x_src - avg_var_kernel_radius] + - varbuf2[z_src][y_src - avg_var_kernel_radius][x_src + avg_var_kernel_radius + 1] + - varbuf2[z_src][y_src + avg_var_kernel_radius + 1][x_src - avg_var_kernel_radius] + varbuf2[z_src][y_src + avg_var_kernel_radius + 1][x_src + avg_var_kernel_radius + 1]; + + // the actual variance + double4 variance = mul2 * v2sum - mul1 * (v1sum * v1sum); + + float4 fvar = float4(static_cast < float >(variance.x), + static_cast < float >(variance.y), + static_cast < float >(variance.z), + static_cast < float >(variance.w)); + input_variances[z_dst][y_dst][x_dst] = fvar; + } + } + } + } + delete[]varbuf2[0][0]; + delete[]varbuf1[0][0]; + delete[]varbuf2[0]; + delete[]varbuf1[0]; + delete[]varbuf2; + delete[]varbuf1; +} + + +static void allocate_input_average_and_variance_buffers(int xsize, int ysize, int zsize) +{ + int y, z; + if (input_averages) + { + delete[]input_averages[0][0]; + delete[]input_averages[0]; + delete[]input_averages; + } + if (input_variances) + { + delete[]input_variances[0][0]; + delete[]input_variances[0]; + delete[]input_variances; + } + if (input_alpha_averages) + { + delete[]input_alpha_averages[0][0]; + delete[]input_alpha_averages[0]; + delete[]input_alpha_averages; + } + + input_averages = new float4 **[zsize]; + input_variances = new float4 **[zsize]; + input_alpha_averages = new float **[zsize]; + + + input_averages[0] = new float4 *[ysize * zsize]; + input_variances[0] = new float4 *[ysize * zsize]; + input_alpha_averages[0] = new float *[ysize * zsize]; + + input_averages[0][0] = new float4[xsize * ysize * zsize]; + input_variances[0][0] = new float4[xsize * ysize * zsize]; + input_alpha_averages[0][0] = new float[xsize * ysize * zsize]; + + for (z = 1; z < zsize; z++) + { + input_averages[z] = input_averages[0] + z * ysize; + input_variances[z] = input_variances[0] + z * ysize; + input_alpha_averages[z] = input_alpha_averages[0] + z * ysize; + + input_averages[z][0] = input_averages[0][0] + z * ysize * xsize; + input_variances[z][0] = input_variances[0][0] + z * ysize * xsize; + input_alpha_averages[z][0] = input_alpha_averages[0][0] + z * ysize * xsize; + } + + for (z = 0; z < zsize; z++) + for (y = 1; y < ysize; y++) + { + input_averages[z][y] = input_averages[z][0] + y * xsize; + input_variances[z][y] = input_variances[z][0] + y * xsize; + input_alpha_averages[z][y] = input_alpha_averages[z][0] + y * xsize; + } + +} + + +// compute averages and variances for the current input image. +void compute_averages_and_variances(const astc_codec_image * img, float rgb_power_to_use, float alpha_power_to_use, int avg_var_kernel_radius, int alpha_kernel_radius, swizzlepattern swz) +{ + int xsize = img->xsize; + int ysize = img->ysize; + int zsize = img->zsize; + allocate_input_average_and_variance_buffers(xsize, ysize, zsize); + + + int x, y, z; + for (z = 0; z < zsize; z += 32) + { + int zblocksize = MIN(32, zsize - z); + for (y = 0; y < ysize; y += 32) + { + int yblocksize = MIN(32, ysize - y); + for (x = 0; x < xsize; x += 32) + { + int xblocksize = MIN(32, xsize - x); + compute_pixel_region_variance(img, + rgb_power_to_use, + alpha_power_to_use, + swz, + (zsize > 1), + x + img->padding, + y + img->padding, z + (zsize > 1 ? img->padding : 0), xblocksize, yblocksize, zblocksize, avg_var_kernel_radius, alpha_kernel_radius, x, y, z); + } + } + } +} diff --git a/third_party/astcenc/Source/astc_decompress_symbolic.cpp b/third_party/astcenc/Source/astc_decompress_symbolic.cpp new file mode 100644 index 0000000000..89ff3441b3 --- /dev/null +++ b/third_party/astcenc/Source/astc_decompress_symbolic.cpp @@ -0,0 +1,317 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Decompress a block of colors, expressed as a symbolic block, + * for ASTC. + */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "astc_codec_internals.h" + +#include "softfloat.h" +#include + +int compute_value_of_texel_int(int texel_to_get, const decimation_table * it, const int *weights) +{ + int i; + int summed_value = 8; + int weights_to_evaluate = it->texel_num_weights[texel_to_get]; + for (i = 0; i < weights_to_evaluate; i++) + { + summed_value += weights[it->texel_weights[texel_to_get][i]] * it->texel_weights_int[texel_to_get][i]; + } + return summed_value >> 4; +} + + +ushort4 lerp_color_int(astc_decode_mode decode_mode, ushort4 color0, ushort4 color1, int weight, int plane2_weight, int plane2_color_component // -1 in 1-plane mode + ) +{ + int4 ecolor0 = int4(color0.x, color0.y, color0.z, color0.w); + int4 ecolor1 = int4(color1.x, color1.y, color1.z, color1.w); + + int4 eweight1 = int4(weight, weight, weight, weight); + switch (plane2_color_component) + { + case 0: + eweight1.x = plane2_weight; + break; + case 1: + eweight1.y = plane2_weight; + break; + case 2: + eweight1.z = plane2_weight; + break; + case 3: + eweight1.w = plane2_weight; + break; + default: + break; + } + + int4 eweight0 = int4(64, 64, 64, 64) - eweight1; + + if (decode_mode == DECODE_LDR_SRGB) + { + ecolor0 = ecolor0 >> 8; + ecolor1 = ecolor1 >> 8; + } + int4 color = (ecolor0 * eweight0) + (ecolor1 * eweight1) + int4(32, 32, 32, 32); + color = color >> 6; + if (decode_mode == DECODE_LDR_SRGB) + color = color | (color << 8); + + ushort4 rcolor = ushort4(color.x, color.y, color.z, color.w); + return rcolor; +} + + +void decompress_symbolic_block(astc_decode_mode decode_mode, + int xdim, int ydim, int zdim, // dimensions of block + int xpos, int ypos, int zpos, // position of block + const symbolic_compressed_block * scb, imageblock * blk) +{ + blk->xpos = xpos; + blk->ypos = ypos; + blk->zpos = zpos; + + int i; + + // if we detected an error-block, blow up immediately. + if (scb->error_block) + { + if (decode_mode == DECODE_LDR_SRGB) + { + for (i = 0; i < xdim * ydim * zdim; i++) + { + blk->orig_data[4 * i] = 1.0f; + blk->orig_data[4 * i + 1] = 0.0f; + blk->orig_data[4 * i + 2] = 1.0f; + blk->orig_data[4 * i + 3] = 1.0f; + blk->rgb_lns[i] = 0; + blk->alpha_lns[i] = 0; + blk->nan_texel[i] = 0; + } + } + else + { + for (i = 0; i < xdim * ydim * zdim; i++) + { + blk->orig_data[4 * i] = 0.0f; + blk->orig_data[4 * i + 1] = 0.0f; + blk->orig_data[4 * i + 2] = 0.0f; + blk->orig_data[4 * i + 3] = 0.0f; + blk->rgb_lns[i] = 0; + blk->alpha_lns[i] = 0; + blk->nan_texel[i] = 1; + } + } + + imageblock_initialize_work_from_orig(blk, xdim * ydim * zdim); + update_imageblock_flags(blk, xdim, ydim, zdim); + return; + } + + + + + if (scb->block_mode < 0) + { + float red = 0, green = 0, blue = 0, alpha = 0; + int use_lns = 0; + int use_nan = 0; + + if (scb->block_mode == -2) + { + // For sRGB decoding, we should return only the top 8 bits. + int mask = (decode_mode == DECODE_LDR_SRGB) ? 0xFF00 : 0xFFFF; + + red = sf16_to_float(unorm16_to_sf16(scb->constant_color[0] & mask)); + green = sf16_to_float(unorm16_to_sf16(scb->constant_color[1] & mask)); + blue = sf16_to_float(unorm16_to_sf16(scb->constant_color[2] & mask)); + alpha = sf16_to_float(unorm16_to_sf16(scb->constant_color[3] & mask)); + use_lns = 0; + use_nan = 0; + } + else + { + switch (decode_mode) + { + case DECODE_LDR_SRGB: + red = 1.0f; + green = 0.0f; + blue = 1.0f; + alpha = 1.0f; + use_lns = 0; + use_nan = 0; + break; + case DECODE_LDR: + red = 0.0f; + green = 0.0f; + blue = 0.0f; + alpha = 0.0f; + use_lns = 0; + use_nan = 1; + break; + case DECODE_HDR: + // constant-color block; unpack from FP16 to FP32. + red = sf16_to_float(scb->constant_color[0]); + green = sf16_to_float(scb->constant_color[1]); + blue = sf16_to_float(scb->constant_color[2]); + alpha = sf16_to_float(scb->constant_color[3]); + use_lns = 1; + use_nan = 0; + break; + } + } + + for (i = 0; i < xdim * ydim * zdim; i++) + { + blk->orig_data[4 * i] = red; + blk->orig_data[4 * i + 1] = green; + blk->orig_data[4 * i + 2] = blue; + blk->orig_data[4 * i + 3] = alpha; + blk->rgb_lns[i] = use_lns; + blk->alpha_lns[i] = use_lns; + blk->nan_texel[i] = use_nan; + } + + + imageblock_initialize_work_from_orig(blk, xdim * ydim * zdim); + update_imageblock_flags(blk, xdim, ydim, zdim); + return; + } + + + // get the appropriate partition-table entry + int partition_count = scb->partition_count; + const partition_info *pt = get_partition_table(xdim, ydim, zdim, partition_count); + pt += scb->partition_index; + + // get the appropriate block descriptor + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + const decimation_table *const *ixtab2 = bsd->decimation_tables; + + + const decimation_table *it = ixtab2[bsd->block_modes[scb->block_mode].decimation_mode]; + + int is_dual_plane = bsd->block_modes[scb->block_mode].is_dual_plane; + + int weight_quantization_level = bsd->block_modes[scb->block_mode].quantization_mode; + + + // decode the color endpoints + ushort4 color_endpoint0[4]; + ushort4 color_endpoint1[4]; + int rgb_hdr_endpoint[4]; + int alpha_hdr_endpoint[4]; + int nan_endpoint[4]; + + for (i = 0; i < partition_count; i++) + unpack_color_endpoints(decode_mode, + scb->color_formats[i], + scb->color_quantization_level, scb->color_values[i], &(rgb_hdr_endpoint[i]), &(alpha_hdr_endpoint[i]), &(nan_endpoint[i]), &(color_endpoint0[i]), &(color_endpoint1[i])); + + + + + + // first unquantize the weights + int uq_plane1_weights[MAX_WEIGHTS_PER_BLOCK]; + int uq_plane2_weights[MAX_WEIGHTS_PER_BLOCK]; + int weight_count = it->num_weights; + + + const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[weight_quantization_level]); + + for (i = 0; i < weight_count; i++) + { + uq_plane1_weights[i] = qat->unquantized_value[scb->plane1_weights[i]]; + } + if (is_dual_plane) + { + for (i = 0; i < weight_count; i++) + uq_plane2_weights[i] = qat->unquantized_value[scb->plane2_weights[i]]; + } + + + // then undecimate them. + int weights[MAX_TEXELS_PER_BLOCK]; + int plane2_weights[MAX_TEXELS_PER_BLOCK]; + + + int texels_per_block = xdim * ydim * zdim; + for (i = 0; i < texels_per_block; i++) + weights[i] = compute_value_of_texel_int(i, it, uq_plane1_weights); + + if (is_dual_plane) + for (i = 0; i < texels_per_block; i++) + plane2_weights[i] = compute_value_of_texel_int(i, it, uq_plane2_weights); + + + int plane2_color_component = scb->plane2_color_component; + + + // now that we have endpoint colors and weights, we can unpack actual colors for + // each texel. + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + + ushort4 color = lerp_color_int(decode_mode, + color_endpoint0[partition], + color_endpoint1[partition], + weights[i], + plane2_weights[i], + is_dual_plane ? plane2_color_component : -1); + + blk->rgb_lns[i] = rgb_hdr_endpoint[partition]; + blk->alpha_lns[i] = alpha_hdr_endpoint[partition]; + blk->nan_texel[i] = nan_endpoint[partition]; + + blk->work_data[4 * i] = color.x; + blk->work_data[4 * i + 1] = color.y; + blk->work_data[4 * i + 2] = color.z; + blk->work_data[4 * i + 3] = color.w; + } + + imageblock_initialize_orig_from_work(blk, xdim * ydim * zdim); + + update_imageblock_flags(blk, xdim, ydim, zdim); +} + + + +float compute_imageblock_difference(int xdim, int ydim, int zdim, const imageblock * p1, const imageblock * p2, const error_weight_block * ewb) +{ + int i; + int texels_per_block = xdim * ydim * zdim; + float summa = 0.0f; + const float *f1 = p1->work_data; + const float *f2 = p2->work_data; + for (i = 0; i < texels_per_block; i++) + { + float rdiff = fabsf(f1[4 * i] - f2[4 * i]); + float gdiff = fabs(f1[4 * i + 1] - f2[4 * i + 1]); + float bdiff = fabs(f1[4 * i + 2] - f2[4 * i + 2]); + float adiff = fabs(f1[4 * i + 3] - f2[4 * i + 3]); + rdiff = MIN(rdiff, 1e15f); + gdiff = MIN(gdiff, 1e15f); + bdiff = MIN(bdiff, 1e15f); + adiff = MIN(adiff, 1e15f); + + summa += rdiff * rdiff * ewb->error_weights[i].x + gdiff * gdiff * ewb->error_weights[i].y + bdiff * bdiff * ewb->error_weights[i].z + adiff * adiff * ewb->error_weights[i].w; + } + + return summa; +} diff --git a/third_party/astcenc/Source/astc_encoding_choice_error.cpp b/third_party/astcenc/Source/astc_encoding_choice_error.cpp new file mode 100644 index 0000000000..5da893bb44 --- /dev/null +++ b/third_party/astcenc/Source/astc_encoding_choice_error.cpp @@ -0,0 +1,310 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Determine color errors for ASTC compression. + * + * We assume that there are two independent sources of color error in + * any given partition. + * + * These are: + * * quantization errors + * * encoding choice errors + * + * Encoding choice errors are errors that come due to encoding choice, + * such as: + * * using luminance instead of RGB + * * using RGB-scale instead of two RGB endpoints. + * * dropping Alpha + * + * Quantization errors occur due to the limited precision we use for + * storing numbers. + * + * Quantization 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, quantization error for red and + * green is halved. + * * quantization error is higher for the HDR endpoint modes. + * + * Other than these errors, quantization error is assumed to be + * proportional to the quantization step. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include + +#ifdef DEBUG_PRINT_DIAGNOSTICS + #include +#endif + +// helper function to merge two endpoint-colors +void merge_endpoints(const endpoints * ep1, // contains three of the color components + const endpoints * ep2, // contains the remaining color component + int separate_component, endpoints * res) +{ + int i; + int partition_count = ep1->partition_count; + res->partition_count = partition_count; + for (i = 0; i < partition_count; i++) + { + res->endpt0[i] = ep1->endpt0[i]; + res->endpt1[i] = ep1->endpt1[i]; + } + + switch (separate_component) + { + case 0: + for (i = 0; i < partition_count; i++) + { + res->endpt0[i].x = ep2->endpt0[i].x; + res->endpt1[i].x = ep2->endpt1[i].x; + } + break; + case 1: + for (i = 0; i < partition_count; i++) + { + res->endpt0[i].y = ep2->endpt0[i].y; + res->endpt1[i].y = ep2->endpt1[i].y; + } + break; + case 2: + for (i = 0; i < partition_count; i++) + { + res->endpt0[i].z = ep2->endpt0[i].z; + res->endpt1[i].z = ep2->endpt1[i].z; + } + break; + case 3: + for (i = 0; i < partition_count; i++) + { + res->endpt0[i].w = ep2->endpt0[i].w; + res->endpt1[i].w = ep2->endpt1[i].w; + } + break; + } +} + + + +/* + for a given set of input colors and a given partitioning, determine: color error that results + from RGB-scale encoding (relevant for LDR only) color error that results from RGB-lumashift encoding + (relevant for HDR only) color error that results from luminance-encoding color error that results + form dropping alpha. whether we are eligible for offset encoding whether we are eligible for + blue-contraction + + The input data are: color data partitioning error-weight data + */ + + +void compute_encoding_choice_errors(int xdim, int ydim, int zdim, const imageblock * pb, const partition_info * pi, const error_weight_block * ewb, + int separate_component, // component that is separated out in 2-plane mode, -1 in 1-plane mode + encoding_choice_errors * eci) +{ + int i; + + int partition_count = pi->partition_count; + + int texels_per_block = xdim * ydim * zdim; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : texels-per-block=%dx%dx%d, separate_component=%d, partition-count=%d\n", __func__, xdim, ydim, zdim, separate_component, partition_count); + } + #endif + + float3 averages[4]; + float3 directions_rgb[4]; + float2 directions_rg[4]; + float2 directions_rb[4]; + float2 directions_gb[4]; + + float4 error_weightings[4]; + float4 color_scalefactors[4]; + float4 inverse_color_scalefactors[4]; + + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, pi, error_weightings, color_scalefactors); + + compute_averages_and_directions_rgb(pi, pb, ewb, color_scalefactors, averages, directions_rgb, directions_rg, directions_rb, directions_gb); + + line3 uncorr_rgb_lines[4]; + line3 samechroma_rgb_lines[4]; // for LDR-RGB-scale + line3 rgb_luma_lines[4]; // for HDR-RGB-scale + line3 luminance_lines[4]; + + processed_line3 proc_uncorr_rgb_lines[4]; + processed_line3 proc_samechroma_rgb_lines[4]; // for LDR-RGB-scale + processed_line3 proc_rgb_luma_lines[4]; // for HDR-RGB-scale + processed_line3 proc_luminance_lines[4]; + + + for (i = 0; i < partition_count; i++) + { + inverse_color_scalefactors[i].x = 1.0f / MAX(color_scalefactors[i].x, 1e-7f); + inverse_color_scalefactors[i].y = 1.0f / MAX(color_scalefactors[i].y, 1e-7f); + inverse_color_scalefactors[i].z = 1.0f / MAX(color_scalefactors[i].z, 1e-7f); + inverse_color_scalefactors[i].w = 1.0f / MAX(color_scalefactors[i].w, 1e-7f); + + + uncorr_rgb_lines[i].a = averages[i]; + if (dot(directions_rgb[i], directions_rgb[i]) == 0.0f) + uncorr_rgb_lines[i].b = normalize(float3(color_scalefactors[i].xyz)); + else + uncorr_rgb_lines[i].b = normalize(directions_rgb[i]); + + samechroma_rgb_lines[i].a = float3(0, 0, 0); + if (dot(averages[i], averages[i]) < 1e-20) + samechroma_rgb_lines[i].b = normalize(float3(color_scalefactors[i].xyz)); + else + samechroma_rgb_lines[i].b = normalize(averages[i]); + + rgb_luma_lines[i].a = averages[i]; + rgb_luma_lines[i].b = normalize(color_scalefactors[i].xyz); + + luminance_lines[i].a = float3(0, 0, 0); + luminance_lines[i].b = normalize(color_scalefactors[i].xyz); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Partition %d\n", i); + printf("Average = <%g %g %g>\n", averages[i].x, averages[i].y, averages[i].z); + printf("Uncorr-rgb-line = <%g %g %g> + t<%g %g %g>\n", + uncorr_rgb_lines[i].a.x, uncorr_rgb_lines[i].a.y, uncorr_rgb_lines[i].a.z, uncorr_rgb_lines[i].b.x, uncorr_rgb_lines[i].b.y, uncorr_rgb_lines[i].b.z); + printf("Samechroma-line = t<%g %g %g>\n", samechroma_rgb_lines[i].b.x, samechroma_rgb_lines[i].b.y, samechroma_rgb_lines[i].b.z); + } + #endif + + proc_uncorr_rgb_lines[i].amod = (uncorr_rgb_lines[i].a - uncorr_rgb_lines[i].b * dot(uncorr_rgb_lines[i].a, uncorr_rgb_lines[i].b)) * inverse_color_scalefactors[i].xyz; + proc_uncorr_rgb_lines[i].bs = uncorr_rgb_lines[i].b * color_scalefactors[i].xyz; + proc_uncorr_rgb_lines[i].bis = uncorr_rgb_lines[i].b * inverse_color_scalefactors[i].xyz; + + proc_samechroma_rgb_lines[i].amod = (samechroma_rgb_lines[i].a - samechroma_rgb_lines[i].b * dot(samechroma_rgb_lines[i].a, samechroma_rgb_lines[i].b)) * inverse_color_scalefactors[i].xyz; + proc_samechroma_rgb_lines[i].bs = samechroma_rgb_lines[i].b * color_scalefactors[i].xyz; + proc_samechroma_rgb_lines[i].bis = samechroma_rgb_lines[i].b * inverse_color_scalefactors[i].xyz; + + proc_rgb_luma_lines[i].amod = (rgb_luma_lines[i].a - rgb_luma_lines[i].b * dot(rgb_luma_lines[i].a, rgb_luma_lines[i].b)) * inverse_color_scalefactors[i].xyz; + proc_rgb_luma_lines[i].bs = rgb_luma_lines[i].b * color_scalefactors[i].xyz; + proc_rgb_luma_lines[i].bis = rgb_luma_lines[i].b * inverse_color_scalefactors[i].xyz; + + proc_luminance_lines[i].amod = (luminance_lines[i].a - luminance_lines[i].b * dot(luminance_lines[i].a, luminance_lines[i].b)) * inverse_color_scalefactors[i].xyz; + proc_luminance_lines[i].bs = luminance_lines[i].b * color_scalefactors[i].xyz; + proc_luminance_lines[i].bis = luminance_lines[i].b * inverse_color_scalefactors[i].xyz; + + } + + + + float uncorr_rgb_error[4]; + float samechroma_rgb_error[4]; + float rgb_luma_error[4]; + float luminance_rgb_error[4]; + + + for (i = 0; i < partition_count; i++) + { + + uncorr_rgb_error[i] = compute_error_squared_rgb_single_partition(i, xdim, ydim, zdim, pi, pb, ewb, &(proc_uncorr_rgb_lines[i])); + + samechroma_rgb_error[i] = compute_error_squared_rgb_single_partition(i, xdim, ydim, zdim, pi, pb, ewb, &(proc_samechroma_rgb_lines[i])); + + rgb_luma_error[i] = compute_error_squared_rgb_single_partition(i, xdim, ydim, zdim, pi, pb, ewb, &(proc_rgb_luma_lines[i])); + + luminance_rgb_error[i] = compute_error_squared_rgb_single_partition(i, xdim, ydim, zdim, pi, pb, ewb, &(proc_luminance_lines[i])); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Partition %d : uncorr-error=%g samechroma-error=%g rgb-luma-error=%g lum-error=%g\n", + i, uncorr_rgb_error[i], samechroma_rgb_error[i], rgb_luma_error[i], luminance_rgb_error[i]); + } + #endif + } + + // compute the error that arises from just ditching alpha and RGB + float alpha_drop_error[4]; + float rgb_drop_error[4]; + for (i = 0; i < partition_count; i++) + { + alpha_drop_error[i] = 0; + rgb_drop_error[i] = 0; + } + for (i = 0; i < texels_per_block; i++) + { + int partition = pi->partition_of_texel[i]; + float alpha = pb->work_data[4 * i + 3]; + float default_alpha = pb->alpha_lns[i] ? (float)0x7800 : (float)0xFFFF; + + float omalpha = alpha - default_alpha; + alpha_drop_error[partition] += omalpha * omalpha * ewb->error_weights[i].w; + float red = pb->work_data[4 * i]; + float green = pb->work_data[4 * i + 1]; + float blue = pb->work_data[4 * i + 2]; + rgb_drop_error[partition] += red * red * ewb->error_weights[i].x + green * green * ewb->error_weights[i].y + blue * blue * ewb->error_weights[i].z; + } + + // check if we are eligible for blue-contraction and offset-encoding + + endpoints ep; + if (separate_component == -1) + { + endpoints_and_weights ei; + compute_endpoints_and_ideal_weights_1_plane(xdim, ydim, zdim, pi, pb, ewb, &ei); + ep = ei.ep; + } + else + { + endpoints_and_weights ei1, ei2; + compute_endpoints_and_ideal_weights_2_planes(xdim, ydim, zdim, pi, pb, ewb, separate_component, &ei1, &ei2); + + merge_endpoints(&(ei1.ep), &(ei2.ep), separate_component, &ep); + } + + int eligible_for_offset_encode[4]; + int eligible_for_blue_contraction[4]; + + for (i = 0; i < partition_count; i++) + { + float4 endpt0 = ep.endpt0[i]; + float4 endpt1 = ep.endpt1[i]; + float4 endpt_dif = endpt1 - endpt0; + if (fabs(endpt_dif.x) < (0.12 * 65535.0f) && fabs(endpt_dif.y) < (0.12 * 65535.0f) && fabs(endpt_dif.z) < (0.12 * 65535.0f)) + eligible_for_offset_encode[i] = 1; + else + eligible_for_offset_encode[i] = 0; + endpt0.x += (endpt0.x - endpt0.z); + endpt0.y += (endpt0.y - endpt0.z); + endpt1.x += (endpt1.x - endpt1.z); + endpt1.y += (endpt1.y - endpt1.z); + if (endpt0.x > (0.01f * 65535.0f) && endpt0.x < (0.99f * 65535.0f) + && endpt1.x > (0.01f * 65535.0f) && endpt1.x < (0.99f * 65535.0f) + && endpt0.y > (0.01f * 65535.0f) && endpt0.y < (0.99f * 65535.0f) && endpt1.y > (0.01f * 65535.0f) && endpt1.y < (0.99f * 65535.0f)) + eligible_for_blue_contraction[i] = 1; + else + eligible_for_blue_contraction[i] = 0; + } + + + // finally, gather up our results + for (i = 0; i < partition_count; i++) + { + eci[i].rgb_scale_error = (samechroma_rgb_error[i] - uncorr_rgb_error[i]) * 0.7f; // empirical + eci[i].rgb_luma_error = (rgb_luma_error[i] - uncorr_rgb_error[i]) * 1.5f; // wild guess + eci[i].luminance_error = (luminance_rgb_error[i] - uncorr_rgb_error[i]) * 3.0f; // empirical + eci[i].alpha_drop_error = alpha_drop_error[i] * 3.0f; + eci[i].rgb_drop_error = rgb_drop_error[i] * 3.0f; + eci[i].can_offset_encode = eligible_for_offset_encode[i]; + eci[i].can_blue_contract = eligible_for_blue_contraction[i]; + } +} diff --git a/third_party/astcenc/Source/astc_find_best_partitioning.cpp b/third_party/astcenc/Source/astc_find_best_partitioning.cpp new file mode 100644 index 0000000000..f53ab1c9b3 --- /dev/null +++ b/third_party/astcenc/Source/astc_find_best_partitioning.cpp @@ -0,0 +1,865 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief ASTC encoding of texture + * + * major step 1: + * * find best partitioning assuming uncorrelated colors + * * find best partitioning assuming RGBS color representation + * + * finding best partitioning for a block: + * * for each available partitioning: + * * compute mean-color-value and dominant direction. + * * this defines two lines, both of which go through the + * mean-color-value: + * * one line has a direction defined by the dominant direction; + * this line 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. + * * we then compute, as a sum across the block, the squared-errors + * that result from using the dominant-direction-lines and the + * squared-errors that result from using the 0001-lines. + */ +/*----------------------------------------------------------------------------*/ + +/* + * Partition table representation: + * We have 3 tables, each with 1024 partitionings + * (these correspond to the 3x128 hardware partitionings crossed with all the + * partition-transform modes in the hardware.) + * + * For each partitioning, we have: + * * a 4-entry table indicating how many texels there are in each of the 4 + * partitions. this may be from 2 to about 60 or so. + * * a 64-entry table indicating the partition index of each of the 64 texels + * in the block. each index may be 0, 1, 2 or 3. + * + * each element in the table is an uint8_t indicating partition index (0, 1, 2 or 3) + */ + +#include + +#include "astc_codec_internals.h" + +#ifdef DEBUG_PRINT_DIAGNOSTICS + #include +#endif + +#include "mathlib.h" + +int imageblock_uses_alpha(int xdim, int ydim, int zdim, const imageblock * pb) +{ + IGNORE(xdim); + IGNORE(ydim); + IGNORE(zdim); + + return pb->alpha_max != pb->alpha_min; +} + +static void compute_alpha_minmax(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, float *alpha_min, float *alpha_max) +{ + int i; + int partition_count = pt->partition_count; + + int texels_per_block = xdim * ydim * zdim; + + for (i = 0; i < partition_count; i++) + { + alpha_min[i] = 1e38f; + alpha_max[i] = -1e38f; + } + + for (i = 0; i < texels_per_block; i++) + { + if (ewb->texel_weight[i] > 1e-10) + { + int partition = pt->partition_of_texel[i]; + float alphaval = blk->work_data[4 * i + 3]; + if (alphaval > alpha_max[partition]) + alpha_max[partition] = alphaval; + if (alphaval < alpha_min[partition]) + alpha_min[partition] = alphaval; + } + } + + for (i = 0; i < partition_count; i++) + { + if (alpha_min[i] >= alpha_max[i]) + { + alpha_min[i] = 0; + alpha_max[i] = 1e-10f; + } + } +} + + +static void compute_rgb_minmax(int xdim, + int ydim, + int zdim, + const partition_info * pt, + const imageblock * blk, const error_weight_block * ewb, float *red_min, float *red_max, float *green_min, float *green_max, float *blue_min, float *blue_max) +{ + int i; + int partition_count = pt->partition_count; + int texels_per_block = xdim * ydim * zdim; + + for (i = 0; i < partition_count; i++) + { + red_min[i] = 1e38f; + red_max[i] = -1e38f; + green_min[i] = 1e38f; + green_max[i] = -1e38f; + blue_min[i] = 1e38f; + blue_max[i] = -1e38f; + } + + for (i = 0; i < texels_per_block; i++) + { + if (ewb->texel_weight[i] > 1e-10f) + { + int partition = pt->partition_of_texel[i]; + float redval = blk->work_data[4 * i]; + float greenval = blk->work_data[4 * i + 1]; + float blueval = blk->work_data[4 * i + 2]; + if (redval > red_max[partition]) + red_max[partition] = redval; + if (redval < red_min[partition]) + red_min[partition] = redval; + if (greenval > green_max[partition]) + green_max[partition] = greenval; + if (greenval < green_min[partition]) + green_min[partition] = greenval; + if (blueval > blue_max[partition]) + blue_max[partition] = blueval; + if (blueval < blue_min[partition]) + blue_min[partition] = blueval; + } + } + for (i = 0; i < partition_count; i++) + { + if (red_min[i] >= red_max[i]) + { + red_min[i] = 0.0f; + red_max[i] = 1e-10f; + } + if (green_min[i] >= green_max[i]) + { + green_min[i] = 0.0f; + green_max[i] = 1e-10f; + } + if (blue_min[i] >= blue_max[i]) + { + blue_min[i] = 0.0f; + blue_max[i] = 1e-10f; + } + } +} + + + +void compute_partition_error_color_weightings(int xdim, int ydim, int zdim, const error_weight_block * ewb, const partition_info * pi, float4 error_weightings[4], float4 color_scalefactors[4]) +{ + int i; + int texels_per_block = xdim * ydim * zdim; + int pcnt = pi->partition_count; + for (i = 0; i < pcnt; i++) + error_weightings[i] = float4(1e-12f, 1e-12f, 1e-12f, 1e-12f); + for (i = 0; i < texels_per_block; i++) + { + int part = pi->partition_of_texel[i]; + error_weightings[part] = error_weightings[part] + ewb->error_weights[i]; + } + for (i = 0; i < pcnt; i++) + { + error_weightings[i] = error_weightings[i] * (1.0f / pi->texels_per_partition[i]); + } + for (i = 0; i < pcnt; i++) + { + color_scalefactors[i].x = sqrt(error_weightings[i].x); + color_scalefactors[i].y = sqrt(error_weightings[i].y); + color_scalefactors[i].z = sqrt(error_weightings[i].z); + color_scalefactors[i].w = sqrt(error_weightings[i].w); + } + +} + + +/* + main function to identify the best partitioning for a given number of texels */ + + +void find_best_partitionings(int partition_search_limit, int xdim, int ydim, int zdim, int partition_count, + const imageblock * pb, const error_weight_block * ewb, int candidates_to_return, + // best partitionings to use if the endpoint colors are assumed to be uncorrelated + int *best_partitions_uncorrellated, + // best partitionings to use if the endpoint colors have the same chroma + int *best_partitions_samechroma, + // best partitionings to use if using dual plane of weights + int *best_partitions_dual_weight_planes) +{ + + + int i, j; + + int texels_per_block = xdim * ydim * zdim; + + // constant used to estimate quantization error for a given partitioning; + // the optimal value for this constant depends on bitrate. + // These constants have been determined empirically. + + float weight_imprecision_estim = 100; + + 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; + else + weight_imprecision_estim = 0.055f; + + + int partition_sequence[PARTITION_COUNT]; + + kmeans_compute_partition_ordering(xdim, ydim, zdim, partition_count, pb, partition_sequence); + + + float weight_imprecision_estim_squared = weight_imprecision_estim * weight_imprecision_estim; + +#ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("weight_imprecision_estim = %g\n", weight_imprecision_estim); +#endif + + int uses_alpha = imageblock_uses_alpha(xdim, ydim, zdim, pb); + + const partition_info *ptab = get_partition_table(xdim, ydim, zdim, partition_count); + + // partitioning errors assuming uncorrelated-chrominance endpoints + float uncorr_errors[PARTITION_COUNT]; + // partitioning errors assuming same-chrominance endpoints + float samechroma_errors[PARTITION_COUNT]; + + // partitioning errors assuming that one of the color channels + // is uncorrelated from all the other ones + float separate_errors[4 * PARTITION_COUNT]; + + + float *separate_red_errors = separate_errors; + float *separate_green_errors = separate_errors + PARTITION_COUNT; + float *separate_blue_errors = separate_errors + 2 * PARTITION_COUNT; + float *separate_alpha_errors = separate_errors + 3 * PARTITION_COUNT; + + int defacto_search_limit = PARTITION_COUNT - 1; + + if (uses_alpha) + { + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partition testing with alpha, %d partitions\n\n", partition_count); + #endif + + for (i = 0; i < PARTITION_COUNT; i++) + { + int partition = partition_sequence[i]; + int bk_partition_count = ptab[partition].partition_count; + + if (bk_partition_count < partition_count) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partitioning %d-%d: invalid\n", partition_count, partition); + #endif + + uncorr_errors[i] = 1e35f; + samechroma_errors[i] = 1e35f; + separate_red_errors[i] = 1e35f; + separate_green_errors[i] = 1e35f; + separate_blue_errors[i] = 1e35f; + separate_alpha_errors[i] = 1e35f; + continue; + } + // the sentinel value for partitions above the search limit must be smaller + // than the sentinel value for invalid partitions + if (i >= partition_search_limit) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partitioning %d-%d: excluded from testing\n", partition_count, partition); + #endif + + defacto_search_limit = i; + + uncorr_errors[i] = 1e34f; + samechroma_errors[i] = 1e34f; + separate_red_errors[i] = 1e34f; + separate_green_errors[i] = 1e34f; + separate_blue_errors[i] = 1e34f; + separate_alpha_errors[i] = 1e34f; + break; + } + + // compute the weighting to give to each color channel + // in each partition. + float4 error_weightings[4]; + float4 color_scalefactors[4]; + float4 inverse_color_scalefactors[4]; + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, ptab + partition, error_weightings, color_scalefactors); + + for (j = 0; j < partition_count; j++) + { + inverse_color_scalefactors[j].x = 1.0f / MAX(color_scalefactors[j].x, 1e-7f); + inverse_color_scalefactors[j].y = 1.0f / MAX(color_scalefactors[j].y, 1e-7f); + inverse_color_scalefactors[j].z = 1.0f / MAX(color_scalefactors[j].z, 1e-7f); + inverse_color_scalefactors[j].w = 1.0f / MAX(color_scalefactors[j].w, 1e-7f); + } + + float4 averages[4]; + float4 directions_rgba[4]; + float3 directions_gba[4]; + float3 directions_rba[4]; + float3 directions_rga[4]; + float3 directions_rgb[4]; + + compute_averages_and_directions_rgba(ptab + partition, pb, ewb, color_scalefactors, averages, directions_rgba, directions_gba, directions_rba, directions_rga, directions_rgb); + + line4 uncorr_lines[4]; + line4 samechroma_lines[4]; + line3 separate_red_lines[4]; + line3 separate_green_lines[4]; + line3 separate_blue_lines[4]; + line3 separate_alpha_lines[4]; + + processed_line4 proc_uncorr_lines[4]; + processed_line4 proc_samechroma_lines[4]; + processed_line3 proc_separate_red_lines[4]; + processed_line3 proc_separate_green_lines[4]; + processed_line3 proc_separate_blue_lines[4]; + processed_line3 proc_separate_alpha_lines[4]; + + float uncorr_linelengths[4]; + float samechroma_linelengths[4]; + float separate_red_linelengths[4]; + float separate_green_linelengths[4]; + float separate_blue_linelengths[4]; + float separate_alpha_linelengths[4]; + + + + for (j = 0; j < partition_count; j++) + { + uncorr_lines[j].a = averages[j]; + if (dot(directions_rgba[j], directions_rgba[j]) == 0.0f) + uncorr_lines[j].b = normalize(float4(1, 1, 1, 1)); + else + uncorr_lines[j].b = normalize(directions_rgba[j]); + + proc_uncorr_lines[j].amod = (uncorr_lines[j].a - uncorr_lines[j].b * dot(uncorr_lines[j].a, uncorr_lines[j].b)) * inverse_color_scalefactors[j]; + proc_uncorr_lines[j].bs = (uncorr_lines[j].b * color_scalefactors[j]); + proc_uncorr_lines[j].bis = (uncorr_lines[j].b * inverse_color_scalefactors[j]); + + + samechroma_lines[j].a = float4(0, 0, 0, 0); + if (dot(averages[j], averages[j]) == 0) + samechroma_lines[j].b = normalize(float4(1, 1, 1, 1)); + else + samechroma_lines[j].b = normalize(averages[j]); + + proc_samechroma_lines[j].amod = (samechroma_lines[j].a - samechroma_lines[j].b * dot(samechroma_lines[j].a, samechroma_lines[j].b)) * inverse_color_scalefactors[j]; + proc_samechroma_lines[j].bs = (samechroma_lines[j].b * color_scalefactors[j]); + proc_samechroma_lines[j].bis = (samechroma_lines[j].b * inverse_color_scalefactors[j]); + + separate_red_lines[j].a = averages[j].yzw; + if (dot(directions_gba[j], directions_gba[j]) == 0.0f) + separate_red_lines[j].b = normalize(float3(1, 1, 1)); + else + separate_red_lines[j].b = normalize(directions_gba[j]); + + separate_green_lines[j].a = averages[j].xzw; + if (dot(directions_rba[j], directions_rba[j]) == 0.0f) + separate_green_lines[j].b = normalize(float3(1, 1, 1)); + else + separate_green_lines[j].b = normalize(directions_rba[j]); + + separate_blue_lines[j].a = averages[j].xyw; + if (dot(directions_rga[j], directions_rga[j]) == 0.0f) + separate_blue_lines[j].b = normalize(float3(1, 1, 1)); + else + separate_blue_lines[j].b = normalize(directions_rga[j]); + + separate_alpha_lines[j].a = averages[j].xyz; + if (dot(directions_rgb[j], directions_rgb[j]) == 0.0f) + separate_alpha_lines[j].b = normalize(float3(1, 1, 1)); + else + separate_alpha_lines[j].b = normalize(directions_rgb[j]); + + proc_separate_red_lines[j].amod = (separate_red_lines[j].a - separate_red_lines[j].b * dot(separate_red_lines[j].a, separate_red_lines[j].b)) * inverse_color_scalefactors[j].yzw; + proc_separate_red_lines[j].bs = (separate_red_lines[j].b * color_scalefactors[j].yzw); + proc_separate_red_lines[j].bis = (separate_red_lines[j].b * inverse_color_scalefactors[j].yzw); + + proc_separate_green_lines[j].amod = + (separate_green_lines[j].a - separate_green_lines[j].b * dot(separate_green_lines[j].a, separate_green_lines[j].b)) * inverse_color_scalefactors[j].xzw; + proc_separate_green_lines[j].bs = (separate_green_lines[j].b * color_scalefactors[j].xzw); + proc_separate_green_lines[j].bis = (separate_green_lines[j].b * inverse_color_scalefactors[j].xzw); + + proc_separate_blue_lines[j].amod = (separate_blue_lines[j].a - separate_blue_lines[j].b * dot(separate_blue_lines[j].a, separate_blue_lines[j].b)) * inverse_color_scalefactors[j].xyw; + proc_separate_blue_lines[j].bs = (separate_blue_lines[j].b * color_scalefactors[j].xyw); + proc_separate_blue_lines[j].bis = (separate_blue_lines[j].b * inverse_color_scalefactors[j].xyw); + + proc_separate_alpha_lines[j].amod = + (separate_alpha_lines[j].a - separate_alpha_lines[j].b * dot(separate_alpha_lines[j].a, separate_alpha_lines[j].b)) * inverse_color_scalefactors[j].xyz; + proc_separate_alpha_lines[j].bs = (separate_alpha_lines[j].b * color_scalefactors[j].xyz); + proc_separate_alpha_lines[j].bis = (separate_alpha_lines[j].b * inverse_color_scalefactors[j].xyz); + + } + + float uncorr_error = compute_error_squared_rgba(ptab + partition, + pb, + ewb, + proc_uncorr_lines, + uncorr_linelengths); + float samechroma_error = compute_error_squared_rgba(ptab + partition, + pb, + ewb, + proc_samechroma_lines, + samechroma_linelengths); + + + float separate_red_error = compute_error_squared_gba(ptab + partition, + pb, + ewb, + proc_separate_red_lines, + separate_red_linelengths); + + float separate_green_error = compute_error_squared_rba(ptab + partition, + pb, + ewb, + proc_separate_green_lines, + separate_green_linelengths); + + float separate_blue_error = compute_error_squared_rga(ptab + partition, + pb, + ewb, + proc_separate_blue_lines, + separate_blue_linelengths); + + float separate_alpha_error = compute_error_squared_rgb(ptab + partition, + pb, + ewb, + proc_separate_alpha_lines, + separate_alpha_linelengths); + + // compute minimum & maximum alpha values in each partition + float red_min[4], red_max[4]; + float green_min[4], green_max[4]; + float blue_min[4], blue_max[4]; + float alpha_min[4], alpha_max[4]; + compute_alpha_minmax(xdim, ydim, zdim, ptab + partition, pb, ewb, alpha_min, alpha_max); + + compute_rgb_minmax(xdim, ydim, zdim, ptab + partition, pb, ewb, red_min, red_max, green_min, green_max, blue_min, blue_max); + + /* + 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 (j = 0; j < partition_count; j++) + { + float tpp = (float)(ptab[partition].texels_per_partition[j]); + + float4 ics = inverse_color_scalefactors[j]; + float4 error_weights = error_weightings[j] * (tpp * weight_imprecision_estim_squared); + + float4 uncorr_vector = (uncorr_lines[j].b * uncorr_linelengths[j]) * ics; + float4 samechroma_vector = (samechroma_lines[j].b * samechroma_linelengths[j]) * ics; + float3 separate_red_vector = (separate_red_lines[j].b * separate_red_linelengths[j]) * ics.yzw; + float3 separate_green_vector = (separate_green_lines[j].b * separate_green_linelengths[j]) * ics.xzw; + float3 separate_blue_vector = (separate_blue_lines[j].b * separate_blue_linelengths[j]) * ics.xyw; + float3 separate_alpha_vector = (separate_alpha_lines[j].b * separate_alpha_linelengths[j]) * ics.xyz; + + uncorr_vector = uncorr_vector * uncorr_vector; + samechroma_vector = samechroma_vector * samechroma_vector; + separate_red_vector = separate_red_vector * separate_red_vector; + separate_green_vector = separate_green_vector * separate_green_vector; + separate_blue_vector = separate_blue_vector * separate_blue_vector; + separate_alpha_vector = separate_alpha_vector * separate_alpha_vector; + + uncorr_error += dot(uncorr_vector, error_weights); + samechroma_error += dot(samechroma_vector, error_weights); + separate_red_error += dot(separate_red_vector, error_weights.yzw); + separate_green_error += dot(separate_green_vector, error_weights.xzw); + separate_blue_error += dot(separate_blue_vector, error_weights.xyw); + separate_alpha_error += dot(separate_alpha_vector, error_weights.xyz); + + float red_scalar = (red_max[j] - red_min[j]); + float green_scalar = (green_max[j] - green_min[j]); + float blue_scalar = (blue_max[j] - blue_min[j]); + float alpha_scalar = (alpha_max[j] - alpha_min[j]); + red_scalar *= red_scalar; + green_scalar *= green_scalar; + blue_scalar *= blue_scalar; + alpha_scalar *= alpha_scalar; + separate_red_error += red_scalar * error_weights.x; + separate_green_error += green_scalar * error_weights.y; + separate_blue_error += blue_scalar * error_weights.z; + separate_alpha_error += alpha_scalar * error_weights.w; + } + + uncorr_errors[i] = uncorr_error; + samechroma_errors[i] = samechroma_error; + separate_red_errors[i] = separate_red_error; + separate_green_errors[i] = separate_green_error; + separate_blue_errors[i] = separate_blue_error; + separate_alpha_errors[i] = separate_alpha_error; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partitioning %d-%d errors: uncorr=%g, samechroma=%g, sep-alpha=%g\n", partition_count, i, uncorr_error, samechroma_error, separate_alpha_error); + #endif + } + } + else + { + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partition testing without alpha, %d partitions\n", partition_count); + #endif + + + + for (i = 0; i < PARTITION_COUNT; i++) + { + + int partition = partition_sequence[i]; + + int bk_partition_count = ptab[partition].partition_count; + if (bk_partition_count < partition_count) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partitioning %d-%d: invalid\n", partition_count, i); + #endif + + uncorr_errors[i] = 1e35f; + samechroma_errors[i] = 1e35f; + separate_red_errors[i] = 1e35f; + separate_green_errors[i] = 1e35f; + separate_blue_errors[i] = 1e35f; + continue; + } + // the sentinel value for valid partitions above the search limit must be smaller + // than the sentinel value for invalid partitions + if (i >= partition_search_limit) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf(" Partitioning %d-%d: excluded from testing\n", partition_count, partition); + #endif + + defacto_search_limit = i; + uncorr_errors[i] = 1e34f; + samechroma_errors[i] = 1e34f; + separate_red_errors[i] = 1e34f; + separate_green_errors[i] = 1e34f; + separate_blue_errors[i] = 1e34f; + break; + + } + + // compute the weighting to give to each color channel + // in each partition. + float4 error_weightings[4]; + float4 color_scalefactors[4]; + float4 inverse_color_scalefactors[4]; + + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, ptab + partition, error_weightings, color_scalefactors); + + for (j = 0; j < partition_count; j++) + { + inverse_color_scalefactors[j].x = 1.0f / MAX(color_scalefactors[j].x, 1e-7f); + inverse_color_scalefactors[j].y = 1.0f / MAX(color_scalefactors[j].y, 1e-7f); + inverse_color_scalefactors[j].z = 1.0f / MAX(color_scalefactors[j].z, 1e-7f); + inverse_color_scalefactors[j].w = 1.0f / MAX(color_scalefactors[j].w, 1e-7f); + } + + float3 averages[4]; + float3 directions_rgb[4]; + float2 directions_rg[4]; + float2 directions_rb[4]; + float2 directions_gb[4]; + + compute_averages_and_directions_rgb(ptab + partition, pb, ewb, color_scalefactors, averages, directions_rgb, directions_rg, directions_rb, directions_gb); + + line3 uncorr_lines[4]; + line3 samechroma_lines[4]; + line2 separate_red_lines[4]; + line2 separate_green_lines[4]; + line2 separate_blue_lines[4]; + + processed_line3 proc_uncorr_lines[4]; + processed_line3 proc_samechroma_lines[4]; + + processed_line2 proc_separate_red_lines[4]; + processed_line2 proc_separate_green_lines[4]; + processed_line2 proc_separate_blue_lines[4]; + + float uncorr_linelengths[4]; + float samechroma_linelengths[4]; + float separate_red_linelengths[4]; + float separate_green_linelengths[4]; + float separate_blue_linelengths[4]; + + for (j = 0; j < partition_count; j++) + { + uncorr_lines[j].a = averages[j]; + if (dot(directions_rgb[j], directions_rgb[j]) == 0.0f) + uncorr_lines[j].b = normalize(float3(1, 1, 1)); + else + uncorr_lines[j].b = normalize(directions_rgb[j]); + + + samechroma_lines[j].a = float3(0, 0, 0); + + if (dot(averages[j], averages[j]) == 0.0f) + samechroma_lines[j].b = normalize(float3(1, 1, 1)); + else + samechroma_lines[j].b = normalize(averages[j]); + + proc_uncorr_lines[j].amod = (uncorr_lines[j].a - uncorr_lines[j].b * dot(uncorr_lines[j].a, uncorr_lines[j].b)) * inverse_color_scalefactors[j].xyz; + proc_uncorr_lines[j].bs = (uncorr_lines[j].b * color_scalefactors[j].xyz); + proc_uncorr_lines[j].bis = (uncorr_lines[j].b * inverse_color_scalefactors[j].xyz); + + proc_samechroma_lines[j].amod = (samechroma_lines[j].a - samechroma_lines[j].b * dot(samechroma_lines[j].a, samechroma_lines[j].b)) * inverse_color_scalefactors[j].xyz; + proc_samechroma_lines[j].bs = (samechroma_lines[j].b * color_scalefactors[j].xyz); + proc_samechroma_lines[j].bis = (samechroma_lines[j].b * inverse_color_scalefactors[j].xyz); + + separate_red_lines[j].a = averages[j].yz; + if (dot(directions_gb[j], directions_gb[j]) == 0.0f) + separate_red_lines[j].b = normalize(float2(1, 1)); + else + separate_red_lines[j].b = normalize(directions_gb[j]); + + separate_green_lines[j].a = averages[j].xz; + if (dot(directions_rb[j], directions_rb[j]) == 0.0f) + separate_green_lines[j].b = normalize(float2(1, 1)); + else + separate_green_lines[j].b = normalize(directions_rb[j]); + + separate_blue_lines[j].a = averages[j].xy; + if (dot(directions_rg[j], directions_rg[j]) == 0.0f) + separate_blue_lines[j].b = normalize(float2(1, 1)); + else + separate_blue_lines[j].b = normalize(directions_rg[j]); + + proc_separate_red_lines[j].amod = (separate_red_lines[j].a - separate_red_lines[j].b * dot(separate_red_lines[j].a, separate_red_lines[j].b)) * inverse_color_scalefactors[j].yz; + proc_separate_red_lines[j].bs = (separate_red_lines[j].b * color_scalefactors[j].yz); + proc_separate_red_lines[j].bis = (separate_red_lines[j].b * inverse_color_scalefactors[j].yz); + + proc_separate_green_lines[j].amod = + (separate_green_lines[j].a - separate_green_lines[j].b * dot(separate_green_lines[j].a, separate_green_lines[j].b)) * inverse_color_scalefactors[j].xz; + proc_separate_green_lines[j].bs = (separate_green_lines[j].b * color_scalefactors[j].xz); + proc_separate_green_lines[j].bis = (separate_green_lines[j].b * inverse_color_scalefactors[j].xz); + + proc_separate_blue_lines[j].amod = (separate_blue_lines[j].a - separate_blue_lines[j].b * dot(separate_blue_lines[j].a, separate_blue_lines[j].b)) * inverse_color_scalefactors[j].xy; + proc_separate_blue_lines[j].bs = (separate_blue_lines[j].b * color_scalefactors[j].xy); + proc_separate_blue_lines[j].bis = (separate_blue_lines[j].b * inverse_color_scalefactors[j].xy); + + } + + float uncorr_error = compute_error_squared_rgb(ptab + partition, + pb, + ewb, + proc_uncorr_lines, + uncorr_linelengths); + float samechroma_error = compute_error_squared_rgb(ptab + partition, + pb, + ewb, + proc_samechroma_lines, + samechroma_linelengths); + + float separate_red_error = compute_error_squared_gb(ptab + partition, + pb, + ewb, + proc_separate_red_lines, + separate_red_linelengths); + + float separate_green_error = compute_error_squared_rb(ptab + partition, + pb, + ewb, + proc_separate_green_lines, + separate_green_linelengths); + + float separate_blue_error = compute_error_squared_rg(ptab + partition, + pb, + ewb, + proc_separate_blue_lines, + separate_blue_linelengths); + + float red_min[4], red_max[4]; + float green_min[4], green_max[4]; + float blue_min[4], blue_max[4]; + + + compute_rgb_minmax(xdim, ydim, zdim, ptab + partition, pb, ewb, red_min, red_max, green_min, green_max, blue_min, blue_max); + + + + /* + compute an estimate of error introduced by weight 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 (j = 0; j < partition_count; j++) + { + float tpp = (float)(ptab[partition].texels_per_partition[j]); + + float3 ics = inverse_color_scalefactors[j].xyz; + float3 error_weights = error_weightings[j].xyz * (tpp * weight_imprecision_estim_squared); + + float3 uncorr_vector = (uncorr_lines[j].b * uncorr_linelengths[j]) * ics; + float3 samechroma_vector = (samechroma_lines[j].b * samechroma_linelengths[j]) * ics; + + float2 separate_red_vector = (separate_red_lines[j].b * separate_red_linelengths[j]) * ics.yz; + float2 separate_green_vector = (separate_green_lines[j].b * separate_green_linelengths[j]) * ics.xz; + float2 separate_blue_vector = (separate_blue_lines[j].b * separate_blue_linelengths[j]) * ics.xy; + + uncorr_vector = uncorr_vector * uncorr_vector; + samechroma_vector = samechroma_vector * samechroma_vector; + separate_red_vector = separate_red_vector * separate_red_vector; + separate_green_vector = separate_green_vector * separate_green_vector; + separate_blue_vector = separate_blue_vector * separate_blue_vector; + + uncorr_error += dot(uncorr_vector, error_weights); + samechroma_error += dot(samechroma_vector, error_weights); + separate_red_error += dot(separate_red_vector, error_weights.yz); + separate_green_error += dot(separate_green_vector, error_weights.xz); + separate_blue_error += dot(separate_blue_vector, error_weights.xy); + + float red_scalar = (red_max[j] - red_min[j]); + float green_scalar = (green_max[j] - green_min[j]); + float blue_scalar = (blue_max[j] - blue_min[j]); + + red_scalar *= red_scalar; + green_scalar *= green_scalar; + blue_scalar *= blue_scalar; + + separate_red_error += red_scalar * error_weights.x; + separate_green_error += green_scalar * error_weights.y; + separate_blue_error += blue_scalar * error_weights.z; + } + + + uncorr_errors[i] = uncorr_error; + samechroma_errors[i] = samechroma_error; + + separate_red_errors[i] = separate_red_error; + separate_green_errors[i] = separate_green_error; + separate_blue_errors[i] = separate_blue_error; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Partitioning %d-%d errors: uncorr=%f, samechroma=%f, sep-red=%f, sep-green=%f, sep-blue=%f\n", + partition_count, partition, uncorr_error, samechroma_error, separate_red_error, separate_green_error, separate_blue_error); + #endif + } + } + + + for (i = 0; i < candidates_to_return; i++) + { + int best_uncorr_partition = 0; + int best_samechroma_partition = 0; + float best_uncorr_error = 1e30f; + float best_samechroma_error = 1e30f; + for (j = 0; j <= defacto_search_limit; j++) + { + if (uncorr_errors[j] < best_uncorr_error) + { + best_uncorr_partition = j; + best_uncorr_error = uncorr_errors[j]; + } + } + best_partitions_uncorrellated[i] = partition_sequence[best_uncorr_partition]; + uncorr_errors[best_uncorr_partition] = 1e30f; + samechroma_errors[best_uncorr_partition] = 1e30f; + + for (j = 0; j <= defacto_search_limit; j++) + { + if (samechroma_errors[j] < best_samechroma_error) + { + best_samechroma_partition = j; + best_samechroma_error = samechroma_errors[j]; + } + } + best_partitions_samechroma[i] = partition_sequence[best_samechroma_partition]; + samechroma_errors[best_samechroma_partition] = 1e30f; + uncorr_errors[best_samechroma_partition] = 1e30f; + } + + for (i = 0; i < 2 * candidates_to_return; i++) + { + int best_partition = 0; + float best_partition_error = 1e30f; + + for (j = 0; j <= defacto_search_limit; j++) + { + if (1 || !uses_alpha) + { + if (separate_errors[j] < best_partition_error) + { + best_partition = j; + best_partition_error = separate_errors[j]; + } + if (separate_errors[j + PARTITION_COUNT] < best_partition_error) + { + best_partition = j + PARTITION_COUNT; + best_partition_error = separate_errors[j + PARTITION_COUNT]; + } + if (separate_errors[j + 2 * PARTITION_COUNT] < best_partition_error) + { + best_partition = j + 2 * PARTITION_COUNT; + best_partition_error = separate_errors[j + 2 * PARTITION_COUNT]; + } + } + if (uses_alpha) + { + if (separate_errors[j + 3 * PARTITION_COUNT] < best_partition_error) + { + best_partition = j + 3 * PARTITION_COUNT; + best_partition_error = separate_errors[j + 3 * PARTITION_COUNT]; + } + } + } + + separate_errors[best_partition] = 1e30f; + best_partition = ((best_partition >> PARTITION_BITS) << PARTITION_BITS) | partition_sequence[best_partition & (PARTITION_COUNT - 1)]; + best_partitions_dual_weight_planes[i] = best_partition; + } + +} diff --git a/third_party/astcenc/Source/astc_ideal_endpoints_and_weights.cpp b/third_party/astcenc/Source/astc_ideal_endpoints_and_weights.cpp new file mode 100644 index 0000000000..89d697d136 --- /dev/null +++ b/third_party/astcenc/Source/astc_ideal_endpoints_and_weights.cpp @@ -0,0 +1,2163 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions for computing color endpoints and texel weights. + */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "astc_codec_internals.h" + +#ifdef DEBUG_PRINT_DIAGNOSTICS +#include +#endif + + +#ifdef DEBUG_CAPTURE_NAN + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + + #include +#endif + +static void compute_endpoints_and_ideal_weights_1_component(int xdim, int ydim, int zdim, + const partition_info * pt, const imageblock * blk, + const error_weight_block * ewb, endpoints_and_weights * ei, + int component) +{ + int i; + + int partition_count = pt->partition_count; + ei->ep.partition_count = partition_count; + + float lowvalues[4], highvalues[4]; + float partition_error_scale[4]; + float linelengths_rcp[4]; + + int texels_per_block = xdim * ydim * zdim; + + const float *error_weights; + switch (component) + { + case 0: + error_weights = ewb->texel_weight_r; + break; + case 1: + error_weights = ewb->texel_weight_g; + break; + case 2: + error_weights = ewb->texel_weight_b; + break; + case 3: + error_weights = ewb->texel_weight_a; + break; + default: + error_weights = ewb->texel_weight_r; + ASTC_CODEC_INTERNAL_ERROR; + } + + + for (i = 0; i < partition_count; i++) + { + lowvalues[i] = 1e10; + highvalues[i] = -1e10; + } + + for (i = 0; i < texels_per_block; i++) + { + if (error_weights[i] > 1e-10) + { + float value = blk->work_data[4 * i + component]; + int partition = pt->partition_of_texel[i]; + if (value < lowvalues[partition]) + lowvalues[partition] = value; + if (value > highvalues[partition]) + highvalues[partition] = value; + } + } + + for (i = 0; i < partition_count; i++) + { + float diff = highvalues[i] - lowvalues[i]; + if (diff < 0) + { + lowvalues[i] = 0; + highvalues[i] = 0; + } + if (diff < 1e-7f) + diff = 1e-7f; + partition_error_scale[i] = diff * diff; + linelengths_rcp[i] = 1.0f / diff; + } + + for (i = 0; i < texels_per_block; i++) + { + float value = blk->work_data[4 * i + component]; + int partition = pt->partition_of_texel[i]; + value -= lowvalues[partition]; + value *= linelengths_rcp[partition]; + if (value > 1.0f) + value = 1.0f; + else if (!(value > 0.0f)) + value = 0.0f; + + ei->weights[i] = value; + ei->weight_error_scale[i] = partition_error_scale[partition] * error_weights[i]; + if (astc_isnan(ei->weight_error_scale[i])) + { + ASTC_CODEC_INTERNAL_ERROR; + } + } + + for (i = 0; i < partition_count; i++) + { + ei->ep.endpt0[i] = float4(blk->red_min, blk->green_min, blk->blue_min, blk->alpha_min); + ei->ep.endpt1[i] = float4(blk->red_max, blk->green_max, blk->blue_max, blk->alpha_max); + switch (component) + { + case 0: // red/x + ei->ep.endpt0[i].x = lowvalues[i]; + ei->ep.endpt1[i].x = highvalues[i]; + break; + case 1: // green/y + ei->ep.endpt0[i].y = lowvalues[i]; + ei->ep.endpt1[i].y = highvalues[i]; + break; + case 2: // blue/z + ei->ep.endpt0[i].z = lowvalues[i]; + ei->ep.endpt1[i].z = highvalues[i]; + break; + case 3: // alpha/w + ei->ep.endpt0[i].w = lowvalues[i]; + ei->ep.endpt1[i].w = highvalues[i]; + break; + } + } + + // print all the data that this function computes. + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s: %dx%dx%d texels, %d partitions, component=%d\n", __func__, xdim, ydim, zdim, partition_count, component); + printf("Endpoints:\n"); + for (i = 0; i < partition_count; i++) + { + printf("%d Low: <%g> => <%g %g %g %g>\n", i, lowvalues[i], ei->ep.endpt0[i].x, ei->ep.endpt0[i].y, ei->ep.endpt0[i].z, ei->ep.endpt0[i].w); + printf("%d High: <%g> => <%g %g %g %g>\n", i, highvalues[i], ei->ep.endpt1[i].x, ei->ep.endpt1[i].y, ei->ep.endpt1[i].z, ei->ep.endpt1[i].w); + } + printf("Ideal-weights:\n"); + + for (i = 0; i < texels_per_block; i++) + { + printf("%3d <%2d %2d %2d>=> %g (weight=%g)\n", i, i % xdim, (i / xdim) % ydim, i / (xdim * ydim), ei->weights[i], ei->weight_error_scale[i]); + } + printf("\n"); + } + #endif +} + + +static void compute_endpoints_and_ideal_weights_2_components(int xdim, int ydim, int zdim, const partition_info * pt, + const imageblock * blk, const error_weight_block * ewb, + endpoints_and_weights * ei, int component1, int component2) +{ + int i; + + int partition_count = pt->partition_count; + ei->ep.partition_count = partition_count; + + float4 error_weightings[4]; + float4 color_scalefactors[4]; + + float2 scalefactors[4]; + + const float *error_weights; + if (component1 == 0 && component2 == 1) + error_weights = ewb->texel_weight_rg; + else if (component1 == 0 && component2 == 2) + error_weights = ewb->texel_weight_rb; + else if (component1 == 1 && component2 == 2) + error_weights = ewb->texel_weight_gb; + else + { + error_weights = ewb->texel_weight_rg; + ASTC_CODEC_INTERNAL_ERROR; + } + + int texels_per_block = xdim * ydim * zdim; + + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, pt, error_weightings, color_scalefactors); + + for (i = 0; i < partition_count; i++) + { + float s1 = 0, s2 = 0; + switch (component1) + { + case 0: + s1 = color_scalefactors[i].x; + break; + case 1: + s1 = color_scalefactors[i].y; + break; + case 2: + s1 = color_scalefactors[i].z; + break; + case 3: + s1 = color_scalefactors[i].w; + break; + } + + switch (component2) + { + case 0: + s2 = color_scalefactors[i].x; + break; + case 1: + s2 = color_scalefactors[i].y; + break; + case 2: + s2 = color_scalefactors[i].z; + break; + case 3: + s2 = color_scalefactors[i].w; + break; + } + scalefactors[i] = normalize(float2(s1, s2)) * 1.41421356f; + } + + + float lowparam[4], highparam[4]; + + float2 averages[4]; + float2 directions[4]; + + line2 lines[4]; + float scale[4]; + float length_squared[4]; + + + for (i = 0; i < partition_count; i++) + { + lowparam[i] = 1e10; + highparam[i] = -1e10; + } + + + compute_averages_and_directions_2_components(pt, blk, ewb, scalefactors, component1, component2, averages, directions); + + for (i = 0; i < partition_count; i++) + { + float2 egv = directions[i]; + if (egv.x + egv.y < 0.0f) + directions[i] = float2(0, 0) - egv; + } + + for (i = 0; i < partition_count; i++) + { + lines[i].a = averages[i]; + if (dot(directions[i], directions[i]) == 0.0f) + lines[i].b = normalize(float2(1, 1)); + else + lines[i].b = normalize(directions[i]); + } + + + for (i = 0; i < texels_per_block; i++) + { + if (error_weights[i] > 1e-10) + { + int partition = pt->partition_of_texel[i]; + float2 point = float2(blk->work_data[4 * i + component1], blk->work_data[4 * i + component2]) * scalefactors[partition]; + line2 l = lines[partition]; + float param = dot(point - l.a, l.b); + ei->weights[i] = param; + if (param < lowparam[partition]) + lowparam[partition] = param; + if (param > highparam[partition]) + highparam[partition] = param; + } + else + { + ei->weights[i] = -1e38f; + } + } + + float2 lowvalues[4]; + float2 highvalues[4]; + + + for (i = 0; i < partition_count; i++) + { + float length = highparam[i] - lowparam[i]; + if (length < 0) // case for when none of the texels had any weight + { + lowparam[i] = 0.0f; + highparam[i] = 1e-7f; + } + + // it is possible for a uniform-color partition to produce length=0; this + // causes NaN-production and NaN-propagation later on. Set length to + // a small value to avoid this problem. + if (length < 1e-7f) + length = 1e-7f; + + length_squared[i] = length * length; + scale[i] = 1.0f / length; + + float2 ep0 = lines[i].a + lines[i].b * lowparam[i]; + float2 ep1 = lines[i].a + lines[i].b * highparam[i]; + + ep0 = ep0 / scalefactors[i]; + ep1 = ep1 / scalefactors[i]; + + lowvalues[i] = ep0; + highvalues[i] = ep1; + } + + + for (i = 0; i < partition_count; i++) + { + ei->ep.endpt0[i] = float4(blk->red_min, blk->green_min, blk->blue_min, blk->alpha_min); + ei->ep.endpt1[i] = float4(blk->red_max, blk->green_max, blk->blue_max, blk->alpha_max); + + float2 ep0 = lowvalues[i]; + float2 ep1 = highvalues[i]; + + switch (component1) + { + case 0: + ei->ep.endpt0[i].x = ep0.x; + ei->ep.endpt1[i].x = ep1.x; + break; + case 1: + ei->ep.endpt0[i].y = ep0.x; + ei->ep.endpt1[i].y = ep1.x; + break; + case 2: + ei->ep.endpt0[i].z = ep0.x; + ei->ep.endpt1[i].z = ep1.x; + break; + case 3: + ei->ep.endpt0[i].w = ep0.x; + ei->ep.endpt1[i].w = ep1.x; + break; + } + switch (component2) + { + case 0: + ei->ep.endpt0[i].x = ep0.y; + ei->ep.endpt1[i].x = ep1.y; + break; + case 1: + ei->ep.endpt0[i].y = ep0.y; + ei->ep.endpt1[i].y = ep1.y; + break; + case 2: + ei->ep.endpt0[i].z = ep0.y; + ei->ep.endpt1[i].z = ep1.y; + break; + case 3: + ei->ep.endpt0[i].w = ep0.y; + ei->ep.endpt1[i].w = ep1.y; + break; + } + } + + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + float idx = (ei->weights[i] - lowparam[partition]) * scale[partition]; + if (idx > 1.0f) + idx = 1.0f; + else if (!(idx > 0.0f)) + idx = 0.0f; + + ei->weights[i] = idx; + ei->weight_error_scale[i] = length_squared[partition] * error_weights[i]; + if (astc_isnan(ei->weight_error_scale[i])) + { + ASTC_CODEC_INTERNAL_ERROR; + } + } + + // print all the data that this function computes. + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s: %dx%dx%d texels, %d partitions, component1=%d, component2=%d\n", __func__, xdim, ydim, zdim, partition_count, component1, component2); + printf("Endpoints:\n"); + for (i = 0; i < partition_count; i++) + { + printf("%d Low: <%g %g> => <%g %g %g %g>\n", i, lowvalues[i].x, lowvalues[i].y, ei->ep.endpt0[i].x, ei->ep.endpt0[i].y, ei->ep.endpt0[i].z, ei->ep.endpt0[i].w); + printf("%d High: <%g %g> => <%g %g %g %g>\n", i, highvalues[i].x, highvalues[i].y, ei->ep.endpt1[i].x, ei->ep.endpt1[i].y, ei->ep.endpt1[i].z, ei->ep.endpt1[i].w); + } + printf("Ideal-weights:\n"); + + for (i = 0; i < texels_per_block; i++) + { + printf("%3d <%2d %2d %2d>=> %g (weight=%g)\n", i, i % xdim, (i / xdim) % ydim, i / (xdim * ydim), ei->weights[i], ei->weight_error_scale[i]); + } + printf("\n"); + } + #endif +} + +static void compute_endpoints_and_ideal_weights_3_components(int xdim, int ydim, int zdim, const partition_info * pt, + const imageblock * blk, const error_weight_block * ewb, + endpoints_and_weights * ei, int component1, int component2, int component3) +{ + int i; + + int partition_count = pt->partition_count; + ei->ep.partition_count = partition_count; + + float4 error_weightings[4]; + float4 color_scalefactors[4]; + + float3 scalefactors[4]; + + int texels_per_block = xdim * ydim * zdim; + + const float *error_weights; + if (component1 == 1 && component2 == 2 && component3 == 3) + error_weights = ewb->texel_weight_gba; + else if (component1 == 0 && component2 == 2 && component3 == 3) + error_weights = ewb->texel_weight_rba; + else if (component1 == 0 && component2 == 1 && component3 == 3) + error_weights = ewb->texel_weight_rga; + else if (component1 == 0 && component2 == 1 && component3 == 2) + error_weights = ewb->texel_weight_rgb; + else + { + error_weights = ewb->texel_weight_gba; + ASTC_CODEC_INTERNAL_ERROR; + } + + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, pt, error_weightings, color_scalefactors); + + for (i = 0; i < partition_count; i++) + { + float s1 = 0, s2 = 0, s3 = 0; + switch (component1) + { + case 0: + s1 = color_scalefactors[i].x; + break; + case 1: + s1 = color_scalefactors[i].y; + break; + case 2: + s1 = color_scalefactors[i].z; + break; + case 3: + s1 = color_scalefactors[i].w; + break; + } + + switch (component2) + { + case 0: + s2 = color_scalefactors[i].x; + break; + case 1: + s2 = color_scalefactors[i].y; + break; + case 2: + s2 = color_scalefactors[i].z; + break; + case 3: + s2 = color_scalefactors[i].w; + break; + } + + switch (component3) + { + case 0: + s3 = color_scalefactors[i].x; + break; + case 1: + s3 = color_scalefactors[i].y; + break; + case 2: + s3 = color_scalefactors[i].z; + break; + case 3: + s3 = color_scalefactors[i].w; + break; + } + scalefactors[i] = normalize(float3(s1, s2, s3)) * 1.73205080f; + } + + + float lowparam[4], highparam[4]; + + float3 averages[4]; + float3 directions[4]; + + line3 lines[4]; + float scale[4]; + float length_squared[4]; + + + for (i = 0; i < partition_count; i++) + { + lowparam[i] = 1e10; + highparam[i] = -1e10; + } + + compute_averages_and_directions_3_components(pt, blk, ewb, scalefactors, component1, component2, component3, averages, directions); + + for (i = 0; i < partition_count; i++) + { + float3 direc = directions[i]; + if (direc.x + direc.y + direc.z < 0.0f) + directions[i] = float3(0, 0, 0) - direc; + } + + for (i = 0; i < partition_count; i++) + { + lines[i].a = averages[i]; + if (dot(directions[i], directions[i]) == 0.0f) + lines[i].b = normalize(float3(1, 1, 1)); + else + lines[i].b = normalize(directions[i]); + } + + + for (i = 0; i < texels_per_block; i++) + { + if (error_weights[i] > 1e-10) + { + int partition = pt->partition_of_texel[i]; + float3 point = float3(blk->work_data[4 * i + component1], blk->work_data[4 * i + component2], blk->work_data[4 * i + component3]) * scalefactors[partition]; + line3 l = lines[partition]; + float param = dot(point - l.a, l.b); + ei->weights[i] = param; + if (param < lowparam[partition]) + lowparam[partition] = param; + if (param > highparam[partition]) + highparam[partition] = param; + } + else + { + ei->weights[i] = -1e38f; + } + } + + float3 lowvalues[4]; + float3 highvalues[4]; + + + for (i = 0; i < partition_count; i++) + { + float length = highparam[i] - lowparam[i]; + if (length < 0) // case for when none of the texels had any weight + { + lowparam[i] = 0.0f; + highparam[i] = 1e-7f; + } + + // it is possible for a uniform-color partition to produce length=0; this + // causes NaN-production and NaN-propagation later on. Set length to + // a small value to avoid this problem. + if (length < 1e-7f) + length = 1e-7f; + + length_squared[i] = length * length; + scale[i] = 1.0f / length; + + float3 ep0 = lines[i].a + lines[i].b * lowparam[i]; + float3 ep1 = lines[i].a + lines[i].b * highparam[i]; + + ep0 = ep0 / scalefactors[i]; + ep1 = ep1 / scalefactors[i]; + + + lowvalues[i] = ep0; + highvalues[i] = ep1; + } + + + for (i = 0; i < partition_count; i++) + { + ei->ep.endpt0[i] = float4(blk->red_min, blk->green_min, blk->blue_min, blk->alpha_min); + ei->ep.endpt1[i] = float4(blk->red_max, blk->green_max, blk->blue_max, blk->alpha_max); + + + float3 ep0 = lowvalues[i]; + float3 ep1 = highvalues[i]; + + switch (component1) + { + case 0: + ei->ep.endpt0[i].x = ep0.x; + ei->ep.endpt1[i].x = ep1.x; + break; + case 1: + ei->ep.endpt0[i].y = ep0.x; + ei->ep.endpt1[i].y = ep1.x; + break; + case 2: + ei->ep.endpt0[i].z = ep0.x; + ei->ep.endpt1[i].z = ep1.x; + break; + case 3: + ei->ep.endpt0[i].w = ep0.x; + ei->ep.endpt1[i].w = ep1.x; + break; + } + switch (component2) + { + case 0: + ei->ep.endpt0[i].x = ep0.y; + ei->ep.endpt1[i].x = ep1.y; + break; + case 1: + ei->ep.endpt0[i].y = ep0.y; + ei->ep.endpt1[i].y = ep1.y; + break; + case 2: + ei->ep.endpt0[i].z = ep0.y; + ei->ep.endpt1[i].z = ep1.y; + break; + case 3: + ei->ep.endpt0[i].w = ep0.y; + ei->ep.endpt1[i].w = ep1.y; + break; + } + switch (component3) + { + case 0: + ei->ep.endpt0[i].x = ep0.z; + ei->ep.endpt1[i].x = ep1.z; + break; + case 1: + ei->ep.endpt0[i].y = ep0.z; + ei->ep.endpt1[i].y = ep1.z; + break; + case 2: + ei->ep.endpt0[i].z = ep0.z; + ei->ep.endpt1[i].z = ep1.z; + break; + case 3: + ei->ep.endpt0[i].w = ep0.z; + ei->ep.endpt1[i].w = ep1.z; + break; + } + } + + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + float idx = (ei->weights[i] - lowparam[partition]) * scale[partition]; + if (idx > 1.0f) + idx = 1.0f; + else if (!(idx > 0.0f)) + idx = 0.0f; + + ei->weights[i] = idx; + ei->weight_error_scale[i] = length_squared[partition] * error_weights[i]; + if (astc_isnan(ei->weight_error_scale[i])) + { + ASTC_CODEC_INTERNAL_ERROR; + } + } + + // print all the data that this function computes. + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s: %dx%dx%d texels, %d partitions, component1=%d, component2=%d, component3=%d\n", __func__, xdim, ydim, zdim, partition_count, component1, component2, component3); + printf("Endpoints:\n"); + for (i = 0; i < partition_count; i++) + { + printf("%d Low: <%g %g %f> => <%g %g %g %g>\n", i, lowvalues[i].x, lowvalues[i].y, lowvalues[i].z, ei->ep.endpt0[i].x, ei->ep.endpt0[i].y, ei->ep.endpt0[i].z, ei->ep.endpt0[i].w); + printf("%d High: <%g %g %g> => <%g %g %g %g>\n", i, highvalues[i].x, highvalues[i].y, highvalues[i].z, ei->ep.endpt1[i].x, ei->ep.endpt1[i].y, ei->ep.endpt1[i].z, ei->ep.endpt1[i].w); + } + printf("Ideal-weights:\n"); + + for (i = 0; i < texels_per_block; i++) + { + printf("%3d <%2d %2d %2d>=> %g (weight=%g)\n", i, (i % xdim), (i / xdim) % ydim, i / (xdim * ydim), ei->weights[i], ei->weight_error_scale[i]); + } + printf("\n"); + } + #endif +} + + + +static void compute_endpoints_and_ideal_weights_rgba(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, endpoints_and_weights * ei) +{ + int i; + + + const float *error_weights = ewb->texel_weight; + + int partition_count = pt->partition_count; + float lowparam[4], highparam[4]; + for (i = 0; i < partition_count; i++) + { + lowparam[i] = 1e10; + highparam[i] = -1e10; + } + + float4 averages[4]; + float4 directions_rgba[4]; + float3 directions_gba[4]; + float3 directions_rba[4]; + float3 directions_rga[4]; + float3 directions_rgb[4]; + + line4 lines[4]; + + float scale[4]; + float length_squared[4]; + + float4 error_weightings[4]; + float4 color_scalefactors[4]; + float4 scalefactors[4]; + + int texels_per_block = xdim * ydim * zdim; + + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, pt, error_weightings, color_scalefactors); + + for (i = 0; i < partition_count; i++) + scalefactors[i] = normalize(color_scalefactors[i]) * 2.0f; + + + + compute_averages_and_directions_rgba(pt, blk, ewb, scalefactors, averages, directions_rgba, directions_gba, directions_rba, directions_rga, directions_rgb); + + // if the direction-vector ends up pointing from light to dark, FLIP IT! + // this will make the first endpoint the darkest one. + for (i = 0; i < partition_count; i++) + { + float4 direc = directions_rgba[i]; + if (direc.x + direc.y + direc.z < 0.0f) + directions_rgba[i] = float4(0, 0, 0, 0) - direc; + } + + for (i = 0; i < partition_count; i++) + { + lines[i].a = averages[i]; + if (dot(directions_rgba[i], directions_rgba[i]) == 0.0f) + lines[i].b = normalize(float4(1, 1, 1, 1)); + else + lines[i].b = normalize(directions_rgba[i]); + } + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + for (i = 0; i < partition_count; i++) + { + printf("Direction-vector %d: <%f %f %f %f>\n", i, directions_rgba[i].x, directions_rgba[i].y, directions_rgba[i].z, directions_rgba[i].w); + printf("Line %d A: <%f %f %f %f>\n", i, lines[i].a.x, lines[i].a.y, lines[i].a.z, lines[i].a.w); + printf("Line %d B: <%f %f %f %f>\n", i, lines[i].b.x, lines[i].b.y, lines[i].b.z, lines[i].b.w); + printf("Scalefactors %d: <%f %f %f %f>\n", i, scalefactors[i].x, scalefactors[i].y, scalefactors[i].z, scalefactors[i].w); + } + } + #endif + + + for (i = 0; i < texels_per_block; i++) + { + if (error_weights[i] > 1e-10) + { + int partition = pt->partition_of_texel[i]; + + float4 point = float4(blk->work_data[4 * i], blk->work_data[4 * i + 1], blk->work_data[4 * i + 2], blk->work_data[4 * i + 3]) * scalefactors[partition]; + line4 l = lines[partition]; + + float param = dot(point - l.a, l.b); + ei->weights[i] = param; + if (param < lowparam[partition]) + lowparam[partition] = param; + if (param > highparam[partition]) + highparam[partition] = param; + } + else + { + ei->weights[i] = -1e38f; + } + } + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + for (i = 0; i < partition_count; i++) + printf("Partition %d: Lowparam=%f Highparam=%f\n", i, lowparam[i], highparam[i]); + } + #endif + + + for (i = 0; i < partition_count; i++) + { + float length = highparam[i] - lowparam[i]; + if (length < 0) + { + lowparam[i] = 0.0f; + highparam[i] = 1e-7f; + } + + + // it is possible for a uniform-color partition to produce length=0; this + // causes NaN-production and NaN-propagation later on. Set length to + // a small value to avoid this problem. + if (length < 1e-7f) + length = 1e-7f; + + length_squared[i] = length * length; + scale[i] = 1.0f / length; + + ei->ep.endpt0[i] = (lines[i].a + lines[i].b * lowparam[i]) / scalefactors[i]; + ei->ep.endpt1[i] = (lines[i].a + lines[i].b * highparam[i]) / scalefactors[i]; + } + + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + float idx = (ei->weights[i] - lowparam[partition]) * scale[partition]; + if (idx > 1.0f) + idx = 1.0f; + else if (!(idx > 0.0f)) + idx = 0.0f; + ei->weights[i] = idx; + ei->weight_error_scale[i] = error_weights[i] * length_squared[partition]; + if (astc_isnan(ei->weight_error_scale[i])) + { + ASTC_CODEC_INTERNAL_ERROR; + } + } + + + // print all the data that this function computes. + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s: %dx%dx%d texels, %d partitions\n", __func__, xdim, ydim, zdim, partition_count); + printf("Endpoints:\n"); + for (i = 0; i < partition_count; i++) + { + printf("%d Low: <%g %g %g %g>\n", i, ei->ep.endpt0[i].x, ei->ep.endpt0[i].y, ei->ep.endpt0[i].z, ei->ep.endpt0[i].w); + printf("%d High: <%g %g %g %g>\n", i, ei->ep.endpt1[i].x, ei->ep.endpt1[i].y, ei->ep.endpt1[i].z, ei->ep.endpt1[i].w); + } + printf("\nIdeal-weights:\n"); + + for (i = 0; i < texels_per_block; i++) + { + printf("%3d <%2d %2d %2d>=> %g (weight=%g)\n", i, i % xdim, (i / xdim) % ydim, i / (xdim * ydim), ei->weights[i], ei->weight_error_scale[i]); + } + printf("\n\n"); + } + #endif + +} + + + +/* + + For a given partitioning, compute: for each partition, the ideal endpoint colors; + these define a color line for the partition. for each pixel, the ideal position of the pixel on the partition's + color line. for each pixel, the length of the color line. + + These data allow us to assess the error introduced by removing and quantizing the per-pixel weights. + + */ + +void compute_endpoints_and_ideal_weights_1_plane(int xdim, int ydim, int zdim, const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, endpoints_and_weights * ei) +{ + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("%s: texels_per_block=%dx%dx%d\n\n", __func__, xdim, ydim, zdim); + #endif + + int uses_alpha = imageblock_uses_alpha(xdim, ydim, zdim, blk); + if (uses_alpha) + { + compute_endpoints_and_ideal_weights_rgba(xdim, ydim, zdim, pt, blk, ewb, ei); + } + else + { + compute_endpoints_and_ideal_weights_3_components(xdim, ydim, zdim, pt, blk, ewb, ei, 0, 1, 2); + } +} + + + +void compute_endpoints_and_ideal_weights_2_planes(int xdim, int ydim, int zdim, const partition_info * pt, + const imageblock * blk, const error_weight_block * ewb, int separate_component, + endpoints_and_weights * ei1, endpoints_and_weights * ei2) +{ + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("%s: texels_per_block=%dx%dx%d, separate_component=%d\n\n", __func__, xdim, ydim, zdim, separate_component); + #endif + + int uses_alpha = imageblock_uses_alpha(xdim, ydim, zdim, blk); + switch (separate_component) + { + case 0: // separate weights for red + if (uses_alpha == 1) + compute_endpoints_and_ideal_weights_3_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 1, 2, 3); + else + compute_endpoints_and_ideal_weights_2_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 1, 2); + compute_endpoints_and_ideal_weights_1_component(xdim, ydim, zdim, pt, blk, ewb, ei2, 0); + break; + + case 1: // separate weights for green + if (uses_alpha == 1) + compute_endpoints_and_ideal_weights_3_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 0, 2, 3); + else + compute_endpoints_and_ideal_weights_2_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 0, 2); + compute_endpoints_and_ideal_weights_1_component(xdim, ydim, zdim, pt, blk, ewb, ei2, 1); + break; + + case 2: // separate weights for blue + if (uses_alpha == 1) + compute_endpoints_and_ideal_weights_3_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 0, 1, 3); + else + compute_endpoints_and_ideal_weights_2_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 0, 1); + compute_endpoints_and_ideal_weights_1_component(xdim, ydim, zdim, pt, blk, ewb, ei2, 2); + break; + + case 3: // separate weights for alpha + if (uses_alpha == 0) + { + ASTC_CODEC_INTERNAL_ERROR; + } + compute_endpoints_and_ideal_weights_3_components(xdim, ydim, zdim, pt, blk, ewb, ei1, 0, 1, 2); + + compute_endpoints_and_ideal_weights_1_component(xdim, ydim, zdim, pt, blk, ewb, ei2, 3); + break; + } + +} + + + +/* + After having computed ideal weights for the case where a weight exists for + every texel, 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; this works as follows: + + * First, for each actual weight, perform a weighted averaging based on the + texels affected by the weight. + * Then, set step size to + * Then, repeat: + 1: First, compute for each weight how much the error will change + if we change the weight by an infinitesimal amount. + 2: This produces a vector that points the direction we should step in. + Normalize this vector. + 3: Perform a step + 4: Check if the step actually improved the error. If it did, perform + another step in the same direction; repeat until error no longer + improves. If the *first* step did not improve error, then we halve + the step size. + 5: If the step size dropped down below , + then we quit, else we go back to #1. + + Subroutines: one routine to apply a step and compute the step's effect on + the error one routine to compute the error change of an infinitesimal + weight change + + Data structures needed: + For every decimation pattern, we need: + * For each weight, a list of tuples that tell which texels + the weight influences. + * For each texel, a list of tuples that tell which weights + go into a given texel. +*/ + +float compute_value_of_texel_flt(int texel_to_get, const decimation_table * it, const float *weights) +{ + const uint8_t *texel_weights = it->texel_weights[texel_to_get]; + const float *texel_weights_float = it->texel_weights_float[texel_to_get]; + + return + (weights[texel_weights[0]] * texel_weights_float[0] + weights[texel_weights[1]] * texel_weights_float[1]) + (weights[texel_weights[2]] * texel_weights_float[2] + weights[texel_weights[3]] * texel_weights_float[3]); +} + + +static inline float compute_error_of_texel(const endpoints_and_weights * eai, int texel_to_get, const decimation_table * it, const float *weights) +{ + float current_value = compute_value_of_texel_flt(texel_to_get, it, weights); + float valuedif = current_value - eai->weights[texel_to_get]; + return valuedif * valuedif * eai->weight_error_scale[texel_to_get]; +} + +/* + helper function: given + * for each texel, an ideal weight and an error-modifier these are contained + in an endpoints_and_weights data structure. + * a weight_table data structure + * for each weight, its current value + + compute the change to overall error that results from adding N to the weight +*/ + + +// this routine is rather heavily optimized since it consumes a lot of CPU time. +void compute_two_error_changes_from_perturbing_weight_infill(const endpoints_and_weights * eai, const decimation_table * it, + float *infilled_weights, int weight_to_perturb, + float perturbation1, float perturbation2, float *res1, float *res2) +{ + int num_weights = it->weight_num_texels[weight_to_perturb]; + float error_change0 = 0.0f; + float error_change1 = 0.0f; + int i; + + const uint8_t *weight_texel_ptr = it->weight_texel[weight_to_perturb]; + const float *weights_ptr = it->weights_flt[weight_to_perturb]; + for (i = num_weights - 1; i >= 0; i--) + { + uint8_t weight_texel = weight_texel_ptr[i]; + float weights = weights_ptr[i]; + + float scale = eai->weight_error_scale[weight_texel] * weights; + float old_weight = infilled_weights[weight_texel]; + float ideal_weight = eai->weights[weight_texel]; + + error_change0 += weights * scale; + error_change1 += (old_weight - ideal_weight) * scale; + } + *res1 = error_change0 * (perturbation1 * perturbation1 * (1.0f / (TEXEL_WEIGHT_SUM * TEXEL_WEIGHT_SUM))) + error_change1 * (perturbation1 * (2.0f / TEXEL_WEIGHT_SUM)); + *res2 = error_change0 * (perturbation2 * perturbation2 * (1.0f / (TEXEL_WEIGHT_SUM * TEXEL_WEIGHT_SUM))) + error_change1 * (perturbation2 * (2.0f / TEXEL_WEIGHT_SUM)); +} + + + +float compute_error_of_weight_set(const endpoints_and_weights * eai, const decimation_table * it, const float *weights) +{ + int i; + int texel_count = it->num_texels; + float error_summa = 0.0; + for (i = 0; i < texel_count; i++) + error_summa += compute_error_of_texel(eai, i, it, weights); + return error_summa; +} + + +/* + Given a complete weight set and a decimation table, try to + compute the optimal weight set (assuming infinite precision) + given the selected decimation table. +*/ + +void compute_ideal_weights_for_decimation_table(const endpoints_and_weights * eai, const decimation_table * it, float *weight_set, float *weights) +{ + int i, j, k; + + int blockdim = (int)floor(sqrt((float)it->num_texels) + 0.5f); + int texels_per_block = it->num_texels; + int weight_count = it->num_weights; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : decimation from %d to %d weights\n\n", __func__, it->num_texels, it->num_weights); + printf("Input weight set:\n"); + for (i = 0; i < it->num_texels; i++) + { + printf("%3d <%2d %2d> : %g\n", i, i % blockdim, i / blockdim, eai->weights[i]); + } + printf("\n"); + } + #endif + + + // perform a shortcut in the case of a complete decimation table + if (texels_per_block == weight_count) + { + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("%s : no decimation actually needed: early-out\n\n", __func__); + #endif + + for (i = 0; i < it->num_texels; i++) + { + int texel = it->weight_texel[i][0]; + weight_set[i] = eai->weights[texel]; + weights[i] = eai->weight_error_scale[texel]; + } + return; + } + + + // if the shortcut is not available, we will instead compute a simple estimate + // and perform three rounds of refinement on that estimate. + + float initial_weight_set[MAX_WEIGHTS_PER_BLOCK]; + float infilled_weights[MAX_TEXELS_PER_BLOCK]; + + // compute an initial average for each weight. + for (i = 0; i < weight_count; i++) + { + int texel_count = it->weight_num_texels[i]; + + float weight_weight = 1e-10f; // to avoid 0/0 later on + float initial_weight = 0.0f; + for (j = 0; j < texel_count; j++) + { + int texel = it->weight_texel[i][j]; + float weight = it->weights_flt[i][j]; + float contrib_weight = weight * eai->weight_error_scale[texel]; + weight_weight += contrib_weight; + initial_weight += eai->weights[texel] * contrib_weight; + } + + weights[i] = weight_weight; + weight_set[i] = initial_weight / weight_weight; // this is the 0/0 that is to be avoided. + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + // stash away the initial-weight estimates for later printing + for (i = 0; i < weight_count; i++) + initial_weight_set[i] = weight_set[i]; + } + #endif + + + for (i = 0; i < texels_per_block; i++) + { + infilled_weights[i] = compute_value_of_texel_flt(i, it, weight_set); + } + + const float stepsizes[2] = { 0.25f, 0.125f }; + + for (j = 0; j < 2; j++) + { + float stepsize = stepsizes[j]; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Pass %d, step=%f \n", j, stepsize); + #endif + + for (i = 0; i < weight_count; i++) + { + float weight_val = weight_set[i]; + float error_change_up, error_change_down; + compute_two_error_changes_from_perturbing_weight_infill(eai, it, infilled_weights, i, stepsize, -stepsize, &error_change_up, &error_change_down); + + /* + assume that the error-change function behaves like a quadratic function in the interval examined, + with "error_change_up" and "error_change_down" defining the function at the endpoints + of the interval. Then, find the position where the function's derivative is zero. + + The "fabs(b) >= a" check tests several conditions in one: + if a is negative, then the 2nd derivative of the function is negative; + in this case, f'(x)=0 will maximize error. + If fabs(b) > fabs(a), then f'(x)=0 will lie outside the interval altogether. + If a and b are both 0, then set step to 0; + otherwise, we end up computing 0/0, which produces a lethal NaN. + We can get an a=b=0 situation if an error weight is 0 in the wrong place. + */ + + float step; + float a = (error_change_up + error_change_down) * 2.0f; + float b = error_change_down - error_change_up; + if (fabs(b) >= a) + { + if (a <= 0.0f) + { + if (error_change_up < error_change_down) + step = 1; + else if (error_change_up > error_change_down) + step = -1; + + else + step = 0; + + } + else + { + if (a < 1e-10f) + a = 1e-10f; + step = b / a; + if (step < -1.0f) + step = -1.0f; + else if (step > 1.0f) + step = 1.0f; + } + } + else + step = b / a; + + + step *= stepsize; + float new_weight_val = weight_val + step; + + // update the weight + weight_set[i] = new_weight_val; + // update the infilled-weights + int num_weights = it->weight_num_texels[i]; + float perturbation = (new_weight_val - weight_val) * (1.0f / TEXEL_WEIGHT_SUM); + const uint8_t *weight_texel_ptr = it->weight_texel[i]; + const float *weights_ptr = it->weights_flt[i]; + for (k = num_weights - 1; k >= 0; k--) + { + uint8_t weight_texel = weight_texel_ptr[k]; + float weight_weight = weights_ptr[k]; + infilled_weights[weight_texel] += perturbation * weight_weight; + } + + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("\n"); + #endif + } + + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Error weights, initial-estimates, final-results\n"); + for (i = 0; i < weight_count; i++) + { + printf("%2d -> weight=%g, initial=%g final=%g\n", i, weights[i], initial_weight_set[i], weight_set[i]); + } + printf("\n"); + } + #endif + + return; +} + + + + +/* + For a decimation table, try to compute an optimal weight set, assuming + that the weights are quantized and subject to a transfer function. + + We do this as follows: + First, we take the initial weights and quantize them. This is our initial estimate. + Then, go through the weights one by one; try to perturb then up and down one weight at a + time; apply any perturbations that improve overall error + Repeat until we have made a complete processing pass over all weights without + triggering any perturbations *OR* we have run 4 full passes. +*/ + +void compute_ideal_quantized_weights_for_decimation_table(const endpoints_and_weights * eai, + const decimation_table * it, + float low_bound, float high_bound, const float *weight_set_in, float *weight_set_out, uint8_t * quantized_weight_set, int quantization_level) +{ + int i; + int weight_count = it->num_weights; + int texels_per_block = it->num_texels; + + const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[quantization_level]); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : texels-per-block=%d, weights=%d, quantization-level=%d\n\n", __func__, texels_per_block, weight_count, quantization_level); + + printf("Weight values before quantization:\n"); + for (i = 0; i < weight_count; i++) + printf("%3d : %g\n", i, weight_set_in[i]); + + printf("Low-bound: %f High-bound: %f\n", low_bound, high_bound); + } + #endif + + + // quantize the weight set using both the specified low/high bounds and the + // standard 0..1 weight bounds. + + /* + WTF issue that we need to examine some time + */ + + if (!((high_bound - low_bound) > 0.5f)) + { + low_bound = 0.0f; + high_bound = 1.0f; + } + + float rscale = high_bound - low_bound; + float scale = 1.0f / rscale; + + // rescale the weights so that + // low_bound -> 0 + // high_bound -> 1 + // OK: first, subtract low_bound, then divide by (high_bound - low_bound) + + for (i = 0; i < weight_count; i++) + weight_set_out[i] = (weight_set_in[i] - low_bound) * scale; + + + + static const float quantization_step_table[12] = { + 1.0f / 1.0f, + 1.0f / 2.0f, + 1.0f / 3.0f, + 1.0f / 4.0f, + 1.0f / 5.0f, + 1.0f / 7.0f, + 1.0f / 9.0f, + 1.0f / 11.0f, + 1.0f / 15.0f, + 1.0f / 19.0f, + 1.0f / 23.0f, + 1.0f / 31.0f, + }; + + float quantization_cutoff = quantization_step_table[quantization_level] * 0.333f; + + + int is_perturbable[MAX_WEIGHTS_PER_BLOCK]; + int perturbable_count = 0; + + // quantize the weight set + for (i = 0; i < weight_count; i++) + { + float ix0 = weight_set_out[i]; + if (ix0 < 0.0f) + ix0 = 0.0f; + if (ix0 > 1.0f) + ix0 = 1.0f; + float ix = ix0; + + ix *= 1024.0f; + int ix2 = (int)floor(ix + 0.5f); + int weight = qat->closest_quantized_weight[ix2]; + + ix = qat->unquantized_value_flt[weight]; + weight_set_out[i] = ix; + quantized_weight_set[i] = weight; + + // test whether the error of the weight is greater than 1/3 of the weight spacing; + // if it is not, then it is flagged as "not perturbable". This causes a + // quality loss of about 0.002 dB, which is totally worth the speedup we're getting. + is_perturbable[i] = 0; + if (fabs(ix - ix0) > quantization_cutoff) + { + is_perturbable[i] = 1; + perturbable_count++; + } + } + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Weight values after initial quantization:\n"); + for (i = 0; i < weight_count; i++) + printf("%3d : %g <%d>\n", i, weight_set_out[i], quantized_weight_set[i]); + } + #endif + + + + + // if the decimation table is complete, the quantization above was all we needed to do, + // so we can early-out. + if (it->num_weights == it->num_texels) + { + // invert the weight-scaling that was done initially + // 0 -> low_bound + // 1 -> high_bound + + rscale = high_bound - low_bound; + for (i = 0; i < weight_count; i++) + weight_set_out[i] = (weight_set_out[i] * rscale) + low_bound; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Weight values after adjustment:\n"); + for (i = 0; i < weight_count; i++) + printf("%3d : %g <%d> \n", i, weight_set_out[i], quantized_weight_set[i], weight_set_out[i] - weight_set_in[i]); + printf("\n"); + printf("%s: Early-out\n\n", __func__); + + } + #endif + + return; + } + + + int weights_tested = 0; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + int perturbation_count = 0; + #endif + + // if no weights are flagged as perturbable, don't try to perturb them. + // if only one weight is flagged as perturbable, perturbation is also pointless. + if (perturbable_count > 1) + { + endpoints_and_weights eaix; + for (i = 0; i < texels_per_block; i++) + { + eaix.weights[i] = (eai->weights[i] - low_bound) * scale; + eaix.weight_error_scale[i] = eai->weight_error_scale[i]; + } + + float infilled_weights[MAX_TEXELS_PER_BLOCK]; + for (i = 0; i < texels_per_block; i++) + infilled_weights[i] = compute_value_of_texel_flt(i, it, weight_set_out); + + int weight_to_perturb = 0; + int weights_since_last_perturbation = 0; + int num_weights = it->num_weights; + + while (weights_since_last_perturbation < num_weights && weights_tested < num_weights * 4) + { + int do_quant_mod = 0; + if (is_perturbable[weight_to_perturb]) + { + + int weight_val = quantized_weight_set[weight_to_perturb]; + int weight_next_up = qat->next_quantized_value[weight_val]; + int weight_next_down = qat->prev_quantized_value[weight_val]; + float flt_weight_val = qat->unquantized_value_flt[weight_val]; + float flt_weight_next_up = qat->unquantized_value_flt[weight_next_up]; + float flt_weight_next_down = qat->unquantized_value_flt[weight_next_down]; + + + int do_quant_mod = 0; + + float error_change_up, error_change_down; + + // compute the error change from perturbing the weight either up or down. + compute_two_error_changes_from_perturbing_weight_infill(&eaix, + it, + infilled_weights, + weight_to_perturb, + (flt_weight_next_up - flt_weight_val), (flt_weight_next_down - flt_weight_val), &error_change_up, &error_change_down); + + int new_weight_val; + float flt_new_weight_val; + if (weight_val != weight_next_up && error_change_up < 0.0f) + { + do_quant_mod = 1; + new_weight_val = weight_next_up; + flt_new_weight_val = flt_weight_next_up; + } + else if (weight_val != weight_next_down && error_change_down < 0.0f) + { + do_quant_mod = 1; + new_weight_val = weight_next_down; + flt_new_weight_val = flt_weight_next_down; + } + + + if (do_quant_mod) + { + + // update the weight. + weight_set_out[weight_to_perturb] = flt_new_weight_val; + quantized_weight_set[weight_to_perturb] = new_weight_val; + + // update the infilled-weights + int num_weights = it->weight_num_texels[weight_to_perturb]; + float perturbation = (flt_new_weight_val - flt_weight_val) * (1.0f / TEXEL_WEIGHT_SUM); + const uint8_t *weight_texel_ptr = it->weight_texel[weight_to_perturb]; + const float *weights_ptr = it->weights_flt[weight_to_perturb]; + for (i = num_weights - 1; i >= 0; i--) + { + uint8_t weight_texel = weight_texel_ptr[i]; + float weights = weights_ptr[i]; + infilled_weights[weight_texel] += perturbation * weights; + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Perturbation of weight %d : %g\n", weight_to_perturb, perturbation * (float)TEXEL_WEIGHT_SUM); + perturbation_count++; + } + #endif + } + } + + if (do_quant_mod) + weights_since_last_perturbation = 0; + else + weights_since_last_perturbation++; + + weight_to_perturb++; + if (weight_to_perturb >= num_weights) + weight_to_perturb -= num_weights; + + weights_tested++; + } + } + + // invert the weight-scaling that was done initially + // 0 -> low_bound + // 1 -> high_bound + + + for (i = 0; i < weight_count; i++) + weight_set_out[i] = (weight_set_out[i] * rscale) + low_bound; + + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%d weights, %d weight tests, %d perturbations\n", weight_count, weights_tested, perturbation_count); + printf("Weight values after adjustment:\n"); + for (i = 0; i < weight_count; i++) + printf("%3d : %g <%d>\n", i, weight_set_out[i], quantized_weight_set[i]); + printf("\n"); + } + #endif + +} + + + + + + +static inline float mat_square_sum(mat2 p) +{ + float a = p.v[0].x; + float b = p.v[0].y; + float c = p.v[1].x; + float d = p.v[1].y; + return a * a + b * b + c * c + d * d; +} + + + + + + + + + + +/* + for a given weight set, we wish to recompute the colors so that they are optimal for a particular weight set. */ +void recompute_ideal_colors(int xdim, int ydim, int zdim, int weight_quantization_mode, endpoints * ep, // contains the endpoints we wish to update + float4 * rgbs_vectors, // used to return RGBS-vectors. (endpoint mode #6) + float4 * rgbo_vectors, // used to return RGBO-vectors. (endpoint mode #7) + float2 * lum_vectors, // used to return luminance-vectors. + const uint8_t * weight_set8, // the current set of weight values + const uint8_t * plane2_weight_set8, // NULL if plane 2 is not actually used. + int plane2_color_component, // color component for 2nd plane of weights; -1 if the 2nd plane of weights is not present + const partition_info * pi, const decimation_table * it, const imageblock * pb, // picture-block containing the actual data. + const error_weight_block * ewb) +{ + int i, j; + + int texels_per_block = xdim * ydim * zdim; + + const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[weight_quantization_mode]); + + float weight_set[MAX_WEIGHTS_PER_BLOCK]; + float plane2_weight_set[MAX_WEIGHTS_PER_BLOCK]; + + for (i = 0; i < it->num_weights; i++) + { + weight_set[i] = qat->unquantized_value_flt[weight_set8[i]]; + } + if (plane2_weight_set8) + { + for (i = 0; i < it->num_weights; i++) + plane2_weight_set[i] = qat->unquantized_value_flt[plane2_weight_set8[i]]; + } + + int partition_count = pi->partition_count; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : %dx%dx%d texels_per_block, %d partitions, plane2-color-component=%d\n\n", __func__, xdim, ydim, zdim, partition_count, plane2_color_component); + + printf("Pre-adjustment endpoint-colors: \n"); + for (i = 0; i < partition_count; i++) + { + printf("%d Low <%g %g %g %g>\n", i, ep->endpt0[i].x, ep->endpt0[i].y, ep->endpt0[i].z, ep->endpt0[i].w); + printf("%d High <%g %g %g %g>\n", i, ep->endpt1[i].x, ep->endpt1[i].y, ep->endpt1[i].z, ep->endpt1[i].w); + } + } + #endif + + + mat2 pmat1_red[4], pmat1_green[4], pmat1_blue[4], pmat1_alpha[4], pmat1_lum[4], pmat1_scale[4]; // matrices for plane of weights 1 + mat2 pmat2_red[4], pmat2_green[4], pmat2_blue[4], pmat2_alpha[4]; // matrices for plane of weights 2 + float2 red_vec[4]; + float2 green_vec[4]; + float2 blue_vec[4]; + float2 alpha_vec[4]; + float2 lum_vec[4]; + float2 scale_vec[4]; + + for (i = 0; i < partition_count; i++) + { + for (j = 0; j < 2; j++) + { + pmat1_red[i].v[j] = float2(0, 0); + pmat2_red[i].v[j] = float2(0, 0); + pmat1_green[i].v[j] = float2(0, 0); + pmat2_green[i].v[j] = float2(0, 0); + pmat1_blue[i].v[j] = float2(0, 0); + pmat2_blue[i].v[j] = float2(0, 0); + pmat1_alpha[i].v[j] = float2(0, 0); + pmat2_alpha[i].v[j] = float2(0, 0); + pmat1_lum[i].v[j] = float2(0, 0); + pmat1_scale[i].v[j] = float2(0, 0); + } + red_vec[i] = float2(0, 0); + green_vec[i] = float2(0, 0); + blue_vec[i] = float2(0, 0); + alpha_vec[i] = float2(0, 0); + lum_vec[i] = float2(0, 0); + scale_vec[i] = float2(0, 0); + } + + + float wmin1[4], wmax1[4]; + float wmin2[4], wmax2[4]; + float red_weight_sum[4]; + float green_weight_sum[4]; + float blue_weight_sum[4]; + float alpha_weight_sum[4]; + float lum_weight_sum[4]; + float scale_weight_sum[4]; + + float red_weight_weight_sum[4]; + float green_weight_weight_sum[4]; + float blue_weight_weight_sum[4]; + + float psum[4]; // sum of (weight * qweight^2) across (red,green,blue) + float qsum[4]; // sum of (weight * qweight * texelval) across (red,green,blue) + + + for (i = 0; i < partition_count; i++) + { + wmin1[i] = 1.0f; + wmax1[i] = 0.0f; + wmin2[i] = 1.0f; + wmax2[i] = 0.0f; + red_weight_sum[i] = 1e-17f; + green_weight_sum[i] = 1e-17f; + blue_weight_sum[i] = 1e-17f; + alpha_weight_sum[i] = 1e-17f; + + lum_weight_sum[i] = 1e-17f; + scale_weight_sum[i] = 1e-17f; + + red_weight_weight_sum[i] = 1e-17f; + green_weight_weight_sum[i] = 1e-17f; + blue_weight_weight_sum[i] = 1e-17f; + + psum[i] = 1e-17f; + qsum[i] = 1e-17f; + } + + + // for each partition, compute the direction that an RGB-scale color endpoint pair would have. + float3 rgb_sum[4]; + float3 rgb_weight_sum[4]; + float3 scale_directions[4]; + float scale_min[4]; + float scale_max[4]; + float lum_min[4]; + float lum_max[4]; + + for (i = 0; i < partition_count; i++) + { + rgb_sum[i] = float3(1e-17f, 1e-17f, 1e-17f); + rgb_weight_sum[i] = float3(1e-17f, 1e-17f, 1e-17f); + } + + + for (i = 0; i < texels_per_block; i++) + { + float3 rgb = float3(pb->work_data[4 * i], pb->work_data[4 * i + 1], pb->work_data[4 * i + 2]); + float3 rgb_weight = float3(ewb->texel_weight_r[i], + ewb->texel_weight_g[i], + ewb->texel_weight_b[i]); + + int part = pi->partition_of_texel[i]; + rgb_sum[part] = rgb_sum[part] + (rgb * rgb_weight); + rgb_weight_sum[part] = rgb_weight_sum[part] + rgb_weight; + } + + for (i = 0; i < partition_count; i++) + { + scale_directions[i] = normalize(rgb_sum[i] / rgb_weight_sum[i]); + scale_max[i] = 0.0f; + scale_min[i] = 1e10f; + lum_max[i] = 0.0f; + lum_min[i] = 1e10f; + } + + + + + + for (i = 0; i < texels_per_block; i++) + { + float r = pb->work_data[4 * i]; + float g = pb->work_data[4 * i + 1]; + float b = pb->work_data[4 * i + 2]; + float a = pb->work_data[4 * i + 3]; + + int part = pi->partition_of_texel[i]; + float idx0 = it ? compute_value_of_texel_flt(i, it, weight_set) : weight_set[i]; + float om_idx0 = 1.0f - idx0; + + if (idx0 > wmax1[part]) + wmax1[part] = idx0; + if (idx0 < wmin1[part]) + wmin1[part] = idx0; + + float red_weight = ewb->texel_weight_r[i]; + float green_weight = ewb->texel_weight_g[i]; + float blue_weight = ewb->texel_weight_b[i]; + float alpha_weight = ewb->texel_weight_a[i]; + + float lum_weight = (red_weight + green_weight + blue_weight); + float scale_weight = lum_weight; + + float lum = (r * red_weight + g * green_weight + b * blue_weight) / lum_weight; + float3 scale_direction = scale_directions[part]; + float scale = dot(scale_direction, float3(r, g, b)); + if (lum < lum_min[part]) + lum_min[part] = scale; + if (lum > lum_max[part]) + lum_max[part] = scale; + if (scale < scale_min[part]) + scale_min[part] = scale; + if (scale > scale_max[part]) + scale_max[part] = scale; + + + red_weight_sum[part] += red_weight; + green_weight_sum[part] += green_weight; + blue_weight_sum[part] += blue_weight; + alpha_weight_sum[part] += alpha_weight; + lum_weight_sum[part] += lum_weight; + scale_weight_sum[part] += scale_weight; + + + pmat1_red[part].v[0].x += om_idx0 * om_idx0 * red_weight; + pmat1_red[part].v[0].y += idx0 * om_idx0 * red_weight; + pmat1_red[part].v[1].x += idx0 * om_idx0 * red_weight; + pmat1_red[part].v[1].y += idx0 * idx0 * red_weight; + + pmat1_green[part].v[0].x += om_idx0 * om_idx0 * green_weight; + pmat1_green[part].v[0].y += idx0 * om_idx0 * green_weight; + pmat1_green[part].v[1].x += idx0 * om_idx0 * green_weight; + pmat1_green[part].v[1].y += idx0 * idx0 * green_weight; + + pmat1_blue[part].v[0].x += om_idx0 * om_idx0 * blue_weight; + pmat1_blue[part].v[0].y += idx0 * om_idx0 * blue_weight; + pmat1_blue[part].v[1].x += idx0 * om_idx0 * blue_weight; + pmat1_blue[part].v[1].y += idx0 * idx0 * blue_weight; + + pmat1_alpha[part].v[0].x += om_idx0 * om_idx0 * alpha_weight; + pmat1_alpha[part].v[0].y += idx0 * om_idx0 * alpha_weight; + pmat1_alpha[part].v[1].x += idx0 * om_idx0 * alpha_weight; + pmat1_alpha[part].v[1].y += idx0 * idx0 * alpha_weight; + + pmat1_lum[part].v[0].x += om_idx0 * om_idx0 * lum_weight; + pmat1_lum[part].v[0].y += idx0 * om_idx0 * lum_weight; + pmat1_lum[part].v[1].x += idx0 * om_idx0 * lum_weight; + pmat1_lum[part].v[1].y += idx0 * idx0 * lum_weight; + + pmat1_scale[part].v[0].x += om_idx0 * om_idx0 * scale_weight; + pmat1_scale[part].v[0].y += idx0 * om_idx0 * scale_weight; + pmat1_scale[part].v[1].x += idx0 * om_idx0 * scale_weight; + pmat1_scale[part].v[1].y += idx0 * idx0 * scale_weight; + + float idx1 = 0.0f, om_idx1 = 0.0f; + if (plane2_weight_set8) + { + idx1 = it ? compute_value_of_texel_flt(i, it, plane2_weight_set) : plane2_weight_set[i]; + om_idx1 = 1.0f - idx1; + if (idx1 > wmax2[part]) + wmax2[part] = idx1; + if (idx1 < wmin2[part]) + wmin2[part] = idx1; + + pmat2_red[part].v[0].x += om_idx1 * om_idx1 * red_weight; + pmat2_red[part].v[0].y += idx1 * om_idx1 * red_weight; + pmat2_red[part].v[1].x += idx1 * om_idx1 * red_weight; + pmat2_red[part].v[1].y += idx1 * idx1 * red_weight; + + pmat2_green[part].v[0].x += om_idx1 * om_idx1 * green_weight; + pmat2_green[part].v[0].y += idx1 * om_idx1 * green_weight; + pmat2_green[part].v[1].x += idx1 * om_idx1 * green_weight; + pmat2_green[part].v[1].y += idx1 * idx1 * green_weight; + + pmat2_blue[part].v[0].x += om_idx1 * om_idx1 * blue_weight; + pmat2_blue[part].v[0].y += idx1 * om_idx1 * blue_weight; + pmat2_blue[part].v[1].x += idx1 * om_idx1 * blue_weight; + pmat2_blue[part].v[1].y += idx1 * idx1 * blue_weight; + + pmat2_alpha[part].v[0].x += om_idx1 * om_idx1 * alpha_weight; + pmat2_alpha[part].v[0].y += idx1 * om_idx1 * alpha_weight; + pmat2_alpha[part].v[1].x += idx1 * om_idx1 * alpha_weight; + pmat2_alpha[part].v[1].y += idx1 * idx1 * alpha_weight; + } + + float red_idx = (plane2_color_component == 0) ? idx1 : idx0; + float green_idx = (plane2_color_component == 1) ? idx1 : idx0; + float blue_idx = (plane2_color_component == 2) ? idx1 : idx0; + float alpha_idx = (plane2_color_component == 3) ? idx1 : idx0; + + + red_vec[part].x += (red_weight * r) * (1.0f - red_idx); + green_vec[part].x += (green_weight * g) * (1.0f - green_idx); + blue_vec[part].x += (blue_weight * b) * (1.0f - blue_idx); + alpha_vec[part].x += (alpha_weight * a) * (1.0f - alpha_idx); + lum_vec[part].x += (lum_weight * lum) * om_idx0; + scale_vec[part].x += (scale_weight * scale) * om_idx0; + + red_vec[part].y += (red_weight * r) * red_idx; + green_vec[part].y += (green_weight * g) * green_idx; + blue_vec[part].y += (blue_weight * b) * blue_idx; + alpha_vec[part].y += (alpha_weight * a) * alpha_idx; + lum_vec[part].y += (lum_weight * lum) * idx0; + scale_vec[part].y += (scale_weight * scale) * idx0; + + red_weight_weight_sum[part] += red_weight * red_idx; + green_weight_weight_sum[part] += green_weight * green_idx; + blue_weight_weight_sum[part] += blue_weight * blue_idx; + + psum[part] += red_weight * red_idx * red_idx + green_weight * green_idx * green_idx + blue_weight * blue_idx * blue_idx; + + } + + // calculations specific to mode #7, the HDR RGB-scale mode. + float red_sum[4]; + float green_sum[4]; + float blue_sum[4]; + for (i = 0; i < partition_count; i++) + { + red_sum[i] = red_vec[i].x + red_vec[i].y; + green_sum[i] = green_vec[i].x + green_vec[i].y; + blue_sum[i] = blue_vec[i].x + blue_vec[i].y; + qsum[i] = red_vec[i].y + green_vec[i].y + blue_vec[i].y; + } + + // RGB+offset for HDR endpoint mode #7 + int rgbo_fail[4]; + for (i = 0; i < partition_count; i++) + { + mat4 mod7_mat; + mod7_mat.v[0] = float4(red_weight_sum[i], 0.0f, 0.0f, red_weight_weight_sum[i]); + mod7_mat.v[1] = float4(0.0f, green_weight_sum[i], 0.0f, green_weight_weight_sum[i]); + mod7_mat.v[2] = float4(0.0f, 0.0f, blue_weight_sum[i], blue_weight_weight_sum[i]); + mod7_mat.v[3] = float4(red_weight_weight_sum[i], green_weight_weight_sum[i], blue_weight_weight_sum[i], psum[i]); + + float4 vect = float4(red_sum[i], green_sum[i], blue_sum[i], qsum[i]); + + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + mat4 rmod7_mat = invert(mod7_mat); + float4 rgbovec = transform(rmod7_mat, vect); + rgbo_vectors[i] = rgbovec; + + // we will occasionally get a failure due to a singular matrix. Record whether such a + // failure has taken place; if it did, compute rgbo_vectors[] with a different method + // later on. + float chkval = dot(rgbovec, rgbovec); + rgbo_fail[i] = chkval != chkval; + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + } + + + + // initialize the luminance and scale vectors with a reasonable default, + // just in case the subsequent calculation blows up. + for (i = 0; i < partition_count; i++) + { + + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + float scalediv = scale_min[i] / scale_max[i]; + if (!(scalediv > 0.0f)) + scalediv = 0.0f; // set to zero if scalediv is zero, negative, or NaN. + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + if (scalediv > 1.0f) + scalediv = 1.0f; + + rgbs_vectors[i] = float4(scale_directions[i] * scale_max[i], scalediv); + lum_vectors[i] = float2(lum_min[i], lum_max[i]); + } + + + + for (i = 0; i < partition_count; i++) + { + + if (wmin1[i] >= wmax1[i] * 0.999) + { + // 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. + float4 avg = float4((red_vec[i].x + red_vec[i].y) / red_weight_sum[i], + (green_vec[i].x + green_vec[i].y) / green_weight_sum[i], + (blue_vec[i].x + blue_vec[i].y) / blue_weight_sum[i], + (alpha_vec[i].x + alpha_vec[i].y) / alpha_weight_sum[i]); + + if (plane2_color_component != 0 && avg.x == avg.x) + ep->endpt0[i].x = ep->endpt1[i].x = avg.x; + if (plane2_color_component != 1 && avg.y == avg.y) + ep->endpt0[i].y = ep->endpt1[i].y = avg.y; + if (plane2_color_component != 2 && avg.z == avg.z) + ep->endpt0[i].z = ep->endpt1[i].z = avg.z; + if (plane2_color_component != 3 && avg.w == avg.w) + ep->endpt0[i].w = ep->endpt1[i].w = avg.w; + + rgbs_vectors[i] = float4(scale_directions[i] * scale_max[i], 1.0f); + float lumval = (red_vec[i].x + red_vec[i].y + green_vec[i].x + green_vec[i].y + blue_vec[i].x + blue_vec[i].y) / (red_weight_sum[i] + green_weight_sum[i] + blue_weight_sum[i]); + lum_vectors[i] = float2(lumval, lumval); + } + + else + { + + // otherwise, complete the analytic calculation of ideal-endpoint-values + // for the given set of texel weights and pixel colors. + + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + float red_det1 = determinant(pmat1_red[i]); + float green_det1 = determinant(pmat1_green[i]); + float blue_det1 = determinant(pmat1_blue[i]); + float alpha_det1 = determinant(pmat1_alpha[i]); + float lum_det1 = determinant(pmat1_lum[i]); + float scale_det1 = determinant(pmat1_scale[i]); + + float red_mss1 = mat_square_sum(pmat1_red[i]); + float green_mss1 = mat_square_sum(pmat1_green[i]); + float blue_mss1 = mat_square_sum(pmat1_blue[i]); + float alpha_mss1 = mat_square_sum(pmat1_alpha[i]); + float lum_mss1 = mat_square_sum(pmat1_lum[i]); + float scale_mss1 = mat_square_sum(pmat1_scale[i]); + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Plane-1 partition %d determinants: R=%g G=%g B=%g A=%g L=%g S=%g\n", i, red_det1, green_det1, blue_det1, alpha_det1, lum_det1, scale_det1); + #endif + + pmat1_red[i] = invert(pmat1_red[i]); + pmat1_green[i] = invert(pmat1_green[i]); + pmat1_blue[i] = invert(pmat1_blue[i]); + pmat1_alpha[i] = invert(pmat1_alpha[i]); + pmat1_lum[i] = invert(pmat1_lum[i]); + pmat1_scale[i] = invert(pmat1_scale[i]); + + float4 ep0 = float4(dot(pmat1_red[i].v[0], red_vec[i]), + dot(pmat1_green[i].v[0], green_vec[i]), + dot(pmat1_blue[i].v[0], blue_vec[i]), + dot(pmat1_alpha[i].v[0], alpha_vec[i])); + float4 ep1 = float4(dot(pmat1_red[i].v[1], red_vec[i]), + dot(pmat1_green[i].v[1], green_vec[i]), + dot(pmat1_blue[i].v[1], blue_vec[i]), + dot(pmat1_alpha[i].v[1], alpha_vec[i])); + + float lum_ep0 = dot(pmat1_lum[i].v[0], lum_vec[i]); + float lum_ep1 = dot(pmat1_lum[i].v[1], lum_vec[i]); + float scale_ep0 = dot(pmat1_scale[i].v[0], scale_vec[i]); + float scale_ep1 = dot(pmat1_scale[i].v[1], scale_vec[i]); + + + if (plane2_color_component != 0 && fabs(red_det1) > (red_mss1 * 1e-4f) && ep0.x == ep0.x && ep1.x == ep1.x) + { + ep->endpt0[i].x = ep0.x; + ep->endpt1[i].x = ep1.x; + } + if (plane2_color_component != 1 && fabs(green_det1) > (green_mss1 * 1e-4f) && ep0.y == ep0.y && ep1.y == ep1.y) + { + ep->endpt0[i].y = ep0.y; + ep->endpt1[i].y = ep1.y; + } + if (plane2_color_component != 2 && fabs(blue_det1) > (blue_mss1 * 1e-4f) && ep0.z == ep0.z && ep1.z == ep1.z) + { + ep->endpt0[i].z = ep0.z; + ep->endpt1[i].z = ep1.z; + } + if (plane2_color_component != 3 && fabs(alpha_det1) > (alpha_mss1 * 1e-4f) && ep0.w == ep0.w && ep1.w == ep1.w) + { + ep->endpt0[i].w = ep0.w; + ep->endpt1[i].w = ep1.w; + } + + if (fabs(lum_det1) > (lum_mss1 * 1e-4f) && lum_ep0 == lum_ep0 && lum_ep1 == lum_ep1 && lum_ep0 < lum_ep1) + { + lum_vectors[i].x = lum_ep0; + lum_vectors[i].y = lum_ep1; + } + if (fabs(scale_det1) > (scale_mss1 * 1e-4f) && scale_ep0 == scale_ep0 && scale_ep1 == scale_ep1 && scale_ep0 < scale_ep1) + { + float scalediv = scale_ep0 / scale_ep1; + rgbs_vectors[i] = float4(scale_directions[i] * scale_ep1, scalediv); + } + + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + } + + if (plane2_weight_set8) + { + if (wmin2[i] >= wmax2[i] * 0.999) + { + // 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. + float4 avg = float4((red_vec[i].x + red_vec[i].y) / red_weight_sum[i], + (green_vec[i].x + green_vec[i].y) / green_weight_sum[i], + (blue_vec[i].x + blue_vec[i].y) / blue_weight_sum[i], + (alpha_vec[i].x + alpha_vec[i].y) / alpha_weight_sum[i]); + + if (plane2_color_component == 0 && avg.x == avg.x) + ep->endpt0[i].x = ep->endpt1[i].x = avg.x; + if (plane2_color_component == 1 && avg.y == avg.y) + ep->endpt0[i].y = ep->endpt1[i].y = avg.y; + if (plane2_color_component == 2 && avg.z == avg.z) + ep->endpt0[i].z = ep->endpt1[i].z = avg.z; + if (plane2_color_component == 3 && avg.w == avg.w) + ep->endpt0[i].w = ep->endpt1[i].w = avg.w; + } + else + { + + #ifdef DEBUG_CAPTURE_NAN + fedisableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + // otherwise, complete the analytic calculation of ideal-endpoint-values + // for the given set of texel weights and pixel colors. + float red_det2 = determinant(pmat2_red[i]); + float green_det2 = determinant(pmat2_green[i]); + float blue_det2 = determinant(pmat2_blue[i]); + float alpha_det2 = determinant(pmat2_alpha[i]); + + float red_mss2 = mat_square_sum(pmat2_red[i]); + float green_mss2 = mat_square_sum(pmat2_green[i]); + float blue_mss2 = mat_square_sum(pmat2_blue[i]); + float alpha_mss2 = mat_square_sum(pmat2_alpha[i]); + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("Plane-2 partition %d determinants: R=%g G=%g B=%g A=%g\n", i, red_det2, green_det2, blue_det2, alpha_det2); + #endif + + pmat2_red[i] = invert(pmat2_red[i]); + pmat2_green[i] = invert(pmat2_green[i]); + pmat2_blue[i] = invert(pmat2_blue[i]); + pmat2_alpha[i] = invert(pmat2_alpha[i]); + float4 ep0 = float4(dot(pmat2_red[i].v[0], red_vec[i]), + dot(pmat2_green[i].v[0], green_vec[i]), + dot(pmat2_blue[i].v[0], blue_vec[i]), + dot(pmat2_alpha[i].v[0], alpha_vec[i])); + float4 ep1 = float4(dot(pmat2_red[i].v[1], red_vec[i]), + dot(pmat2_green[i].v[1], green_vec[i]), + dot(pmat2_blue[i].v[1], blue_vec[i]), + dot(pmat2_alpha[i].v[1], alpha_vec[i])); + + if (plane2_color_component == 0 && fabs(red_det2) > (red_mss2 * 1e-4f) && ep0.x == ep0.x && ep1.x == ep1.x) + { + ep->endpt0[i].x = ep0.x; + ep->endpt1[i].x = ep1.x; + } + if (plane2_color_component == 1 && fabs(green_det2) > (green_mss2 * 1e-4f) && ep0.y == ep0.y && ep1.y == ep1.y) + { + ep->endpt0[i].y = ep0.y; + ep->endpt1[i].y = ep1.y; + } + if (plane2_color_component == 2 && fabs(blue_det2) > (blue_mss2 * 1e-4f) && ep0.z == ep0.z && ep1.z == ep1.z) + { + ep->endpt0[i].z = ep0.z; + ep->endpt1[i].z = ep1.z; + } + if (plane2_color_component == 3 && fabs(alpha_det2) > (alpha_mss2 * 1e-4f) && ep0.w == ep0.w && ep1.w == ep1.w) + { + ep->endpt0[i].w = ep0.w; + ep->endpt1[i].w = ep1.w; + } + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + } + } + } + + // if the calculation of an RGB-offset vector failed, try to compute + // a somewhat-sensible value anyway + for (i = 0; i < partition_count; i++) + if (rgbo_fail[i]) + { + float4 v0 = ep->endpt0[i]; + float4 v1 = ep->endpt1[i]; + float avgdif = dot(v1.xyz - v0.xyz, float3(1, 1, 1)) * (1.0f / 3.0f); + if (avgdif <= 0.0f) + avgdif = 0.0f; + float4 avg = (v0 + v1) * 0.5f; + float4 ep0 = avg - float4(avgdif, avgdif, avgdif, avgdif) * 0.5f; + + rgbo_vectors[i] = float4(ep0.xyz, avgdif); + } + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("Post-adjustment endpoint-colors: \n"); + for (i = 0; i < partition_count; i++) + { + printf("%d Low <%g %g %g %g>\n", i, ep->endpt0[i].x, ep->endpt0[i].y, ep->endpt0[i].z, ep->endpt0[i].w); + printf("%d High <%g %g %g %g>\n", i, ep->endpt1[i].x, ep->endpt1[i].y, ep->endpt1[i].z, ep->endpt1[i].w); + + printf("%d RGBS: <%g %g %g %g>\n", i, rgbs_vectors[i].x, rgbs_vectors[i].y, rgbs_vectors[i].z, rgbs_vectors[i].w); + + printf("%d RGBO <%g %g %g %g>\n", i, rgbo_vectors[i].x, rgbo_vectors[i].y, rgbo_vectors[i].z, rgbo_vectors[i].w); + + printf("%d Lum: <%g %g>\n", i, lum_vectors[i].x, lum_vectors[i].y); + } + } + #endif + +} diff --git a/third_party/astcenc/Source/astc_image_load_store.cpp b/third_party/astcenc/Source/astc_image_load_store.cpp new file mode 100644 index 0000000000..2652f7b399 --- /dev/null +++ b/third_party/astcenc/Source/astc_image_load_store.cpp @@ -0,0 +1,1455 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions for managing ASTC codec images. + */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "astc_codec_internals.h" + +#include "softfloat.h" +#include +#include + +void destroy_image(astc_codec_image * img) +{ + if (img == NULL) + return; + + if (img->imagedata8) + { + delete[]img->imagedata8[0][0]; + delete[]img->imagedata8[0]; + delete[]img->imagedata8; + } + if (img->imagedata16) + { + delete[]img->imagedata16[0][0]; + delete[]img->imagedata16[0]; + delete[]img->imagedata16; + } + delete img; +} + + + +astc_codec_image *allocate_image(int bitness, int xsize, int ysize, int zsize, int padding) +{ + int i, j; + astc_codec_image *img = new astc_codec_image; + img->xsize = xsize; + img->ysize = ysize; + img->zsize = zsize; + img->padding = padding; + + int exsize = xsize + 2 * padding; + int eysize = ysize + 2 * padding; + int ezsize = (zsize == 1) ? 1 : zsize + 2 * padding; + + if (bitness == 8) + { + img->imagedata8 = new uint8_t **[ezsize]; + img->imagedata8[0] = new uint8_t *[ezsize * eysize]; + img->imagedata8[0][0] = new uint8_t[4 * ezsize * eysize * exsize]; + for (i = 1; i < ezsize; i++) + { + img->imagedata8[i] = img->imagedata8[0] + i * eysize; + img->imagedata8[i][0] = img->imagedata8[0][0] + 4 * i * exsize * eysize; + } + for (i = 0; i < ezsize; i++) + for (j = 1; j < eysize; j++) + img->imagedata8[i][j] = img->imagedata8[i][0] + 4 * j * exsize; + + img->imagedata16 = NULL; + } + + else if (bitness == 16) + { + img->imagedata16 = new uint16_t **[ezsize]; + img->imagedata16[0] = new uint16_t *[ezsize * eysize]; + img->imagedata16[0][0] = new uint16_t[4 * ezsize * eysize * exsize]; + for (i = 1; i < ezsize; i++) + { + img->imagedata16[i] = img->imagedata16[0] + i * eysize; + img->imagedata16[i][0] = img->imagedata16[0][0] + 4 * i * exsize * eysize; + } + for (i = 0; i < ezsize; i++) + for (j = 1; j < eysize; j++) + img->imagedata16[i][j] = img->imagedata16[i][0] + 4 * j * exsize; + + img->imagedata8 = NULL; + } + else + { + ASTC_CODEC_INTERNAL_ERROR; + exit(1); + } + + return img; +} + + + +void initialize_image(astc_codec_image * img) +{ + int x, y, z; + + int exsize = img->xsize + 2 * img->padding; + int eysize = img->ysize + 2 * img->padding; + int ezsize = (img->zsize == 1) ? 1 : img->zsize + 2 * img->padding; + + if (img->imagedata8) + { + for (z = 0; z < ezsize; z++) + for (y = 0; y < eysize; y++) + for (x = 0; x < exsize; x++) + { + img->imagedata8[z][y][4 * x] = 0; + img->imagedata8[z][y][4 * x + 1] = 0; + img->imagedata8[z][y][4 * x + 2] = 0; + img->imagedata8[z][y][4 * x + 3] = 0xFF; + } + } + else if (img->imagedata16) + { + for (z = 0; z < ezsize; z++) + for (y = 0; y < eysize; y++) + for (x = 0; x < exsize; x++) + { + img->imagedata16[z][y][4 * x] = 0; + img->imagedata16[z][y][4 * x + 1] = 0; + img->imagedata16[z][y][4 * x + 2] = 0; + img->imagedata16[z][y][4 * x + 3] = 0x3C00; + } + } + else + { + ASTC_CODEC_INTERNAL_ERROR; + exit(1); + } +} + + + + +// fill the padding area of the input-file buffer with clamp-to-edge data +// Done inefficiently, in that it will overwrite all the interior data at least once; +// this is not considered a problem, since this makes up a very small part of total +// running time. + +void fill_image_padding_area(astc_codec_image * img) +{ + if (img->padding == 0) + return; + + int x, y, z, i; + int exsize = img->xsize + 2 * img->padding; + int eysize = img->ysize + 2 * img->padding; + int ezsize = (img->zsize == 1) ? 1 : (img->zsize + 2 * img->padding); + + int xmin = img->padding; + int ymin = img->padding; + int zmin = (img->zsize == 1) ? 0 : img->padding; + int xmax = img->xsize + img->padding - 1; + int ymax = img->ysize + img->padding - 1; + int zmax = (img->zsize == 1) ? 0 : img->zsize + img->padding - 1; + + + // This is a very simple implementation. Possible optimizations include: + // * Testing if texel is outside the edge. + // * Looping over texels that we know are outside the edge. + if (img->imagedata8) + { + for (z = 0; z < ezsize; z++) + { + int zc = MIN(MAX(z, zmin), zmax); + for (y = 0; y < eysize; y++) + { + int yc = MIN(MAX(y, ymin), ymax); + for (x = 0; x < exsize; x++) + { + int xc = MIN(MAX(x, xmin), xmax); + for (i = 0; i < 4; i++) + img->imagedata8[z][y][4 * x + i] = img->imagedata8[zc][yc][4 * xc + i]; + } + } + } + } + else if (img->imagedata16) + { + for (z = 0; z < ezsize; z++) + { + int zc = MIN(MAX(z, zmin), zmax); + for (y = 0; y < eysize; y++) + { + int yc = MIN(MAX(y, ymin), ymax); + for (x = 0; x < exsize; x++) + { + int xc = MIN(MAX(x, xmin), xmax); + for (i = 0; i < 4; i++) + img->imagedata16[z][y][4 * x + i] = img->imagedata16[zc][yc][4 * xc + i]; + } + } + } + } +} + + + + +int determine_image_channels(const astc_codec_image * img) +{ + int x, y, z; + + int xsize = img->xsize; + int ysize = img->ysize; + int zsize = img->zsize; + // scan through the image data + // to determine how many color channels the image has. + + int lum_mask; + int alpha_mask; + int alpha_mask_ref; + if (img->imagedata8) + { + alpha_mask_ref = 0xFF; + alpha_mask = 0xFF; + lum_mask = 0; + for (z = 0; z < zsize; z++) + { + for (y = 0; y < ysize; y++) + { + for (x = 0; x < xsize; x++) + { + int r = img->imagedata8[z][y][4 * x]; + int g = img->imagedata8[z][y][4 * x + 1]; + int b = img->imagedata8[z][y][4 * x + 2]; + int a = img->imagedata8[z][y][4 * x + 3]; + lum_mask |= (r ^ g) | (r ^ b); + alpha_mask &= a; + } + } + } + } + else // if( bitness == 16 ) + { + alpha_mask_ref = 0xFFFF; + alpha_mask = 0xFFFF; + lum_mask = 0; + for (z = 0; z < zsize; z++) + { + for (y = 0; y < ysize; y++) + { + for (x = 0; x < xsize; x++) + { + int r = img->imagedata16[z][y][4 * x]; + int g = img->imagedata16[z][y][4 * x + 1]; + int b = img->imagedata16[z][y][4 * x + 2]; + int a = img->imagedata16[z][y][4 * x + 3]; + lum_mask |= (r ^ g) | (r ^ b); + alpha_mask &= (a ^ 0xC3FF); // a ^ 0xC3FF returns FFFF if and only if the input is 1.0 + } + } + } + } + + int image_channels = 1 + (lum_mask == 0 ? 0 : 2) + (alpha_mask == alpha_mask_ref ? 0 : 1); + + return image_channels; +} + + + + + + +// conversion functions between the LNS representation and the FP16 representation. + +float float_to_lns(float p) +{ + + if (astc_isnan(p) || p <= 1.0f / 67108864.0f) + { + // underflow or NaN value, return 0. + // We count underflow if the input value is smaller than 2^-26. + return 0; + } + + if (fabs(p) >= 65536.0f) + { + // overflow, return a +INF value + return 65535; + } + + int expo; + float normfrac = frexp(p, &expo); + float p1; + if (expo < -13) + { + // input number is smaller than 2^-14. In this case, multiply by 2^25. + p1 = p * 33554432.0f; + expo = 0; + } + else + { + expo += 14; + p1 = (normfrac - 0.5f) * 4096.0f; + } + + if (p1 < 384.0f) + p1 *= 4.0f / 3.0f; + else if (p1 <= 1408.0f) + p1 += 128.0f; + else + p1 = (p1 + 512.0f) * (4.0f / 5.0f); + + p1 += expo * 2048.0f; + return p1 + 1.0f; +} + + + +uint16_t lns_to_sf16(uint16_t p) +{ + + uint16_t mc = p & 0x7FF; + uint16_t ec = p >> 11; + uint16_t mt; + if (mc < 512) + mt = 3 * mc; + else if (mc < 1536) + mt = 4 * mc - 512; + else + mt = 5 * mc - 2048; + + uint16_t res = (ec << 10) | (mt >> 3); + if (res >= 0x7BFF) + res = 0x7BFF; + return res; +} + + +// conversion function from 16-bit LDR value to FP16. +// note: for LDR interpolation, it is impossible to get a denormal result; +// this simplifies the conversion. +// FALSE; we can receive a very small UNORM16 through the constant-block. +uint16_t unorm16_to_sf16(uint16_t p) +{ + if (p == 0xFFFF) + return 0x3C00; // value of 1.0 . + if (p < 4) + return p << 8; + + int lz = clz32(p) - 16; + p <<= (lz + 1); + p >>= 6; + p |= (14 - lz) << 10; + return p; +} + + + + + +void imageblock_initialize_deriv_from_work_and_orig(imageblock * pb, int pixelcount) +{ + int i; + + const float *fptr = pb->orig_data; + const float *wptr = pb->work_data; + float *dptr = pb->deriv_data; + + for (i = 0; i < pixelcount; i++) + { + + // compute derivatives for RGB first + if (pb->rgb_lns[i]) + { + float r = MAX(fptr[0], 6e-5f); + float g = MAX(fptr[1], 6e-5f); + float b = MAX(fptr[2], 6e-5f); + + float rderiv = (float_to_lns(r * 1.05f) - float_to_lns(r)) / (r * 0.05f); + float gderiv = (float_to_lns(g * 1.05f) - float_to_lns(g)) / (g * 0.05f); + float bderiv = (float_to_lns(b * 1.05f) - float_to_lns(b)) / (b * 0.05f); + + // the derivative may not actually take values smaller than 1/32 or larger than 2^25; + // if it does, we clamp it. + if (rderiv < (1.0f / 32.0f)) + rderiv = (1.0f / 32.0f); + else if (rderiv > 33554432.0f) + rderiv = 33554432.0f; + + if (gderiv < (1.0f / 32.0f)) + gderiv = (1.0f / 32.0f); + else if (gderiv > 33554432.0f) + gderiv = 33554432.0f; + + if (bderiv < (1.0f / 32.0f)) + bderiv = (1.0f / 32.0f); + else if (bderiv > 33554432.0f) + bderiv = 33554432.0f; + + dptr[0] = rderiv; + dptr[1] = gderiv; + dptr[2] = bderiv; + } + else + { + dptr[0] = 65535.0f; + dptr[1] = 65535.0f; + dptr[2] = 65535.0f; + } + + + // then compute derivatives for Alpha + if (pb->alpha_lns[i]) + { + float a = MAX(fptr[3], 6e-5f); + float aderiv = (float_to_lns(a * 1.05f) - float_to_lns(a)) / (a * 0.05f); + // the derivative may not actually take values smaller than 1/32 or larger than 2^25; + // if it does, we clamp it. + if (aderiv < (1.0f / 32.0f)) + aderiv = (1.0f / 32.0f); + else if (aderiv > 33554432.0f) + aderiv = 33554432.0f; + + dptr[3] = aderiv; + } + else + { + dptr[3] = 65535.0f; + } + + fptr += 4; + wptr += 4; + dptr += 4; + } +} + + + + +// helper function to initialize the work-data from the orig-data +void imageblock_initialize_work_from_orig(imageblock * pb, int pixelcount) +{ + int i; + float *fptr = pb->orig_data; + float *wptr = pb->work_data; + + for (i = 0; i < pixelcount; i++) + { + if (pb->rgb_lns[i]) + { + wptr[0] = float_to_lns(fptr[0]); + wptr[1] = float_to_lns(fptr[1]); + wptr[2] = float_to_lns(fptr[2]); + } + else + { + wptr[0] = fptr[0] * 65535.0f; + wptr[1] = fptr[1] * 65535.0f; + wptr[2] = fptr[2] * 65535.0f; + } + + if (pb->alpha_lns[i]) + { + wptr[3] = float_to_lns(fptr[3]); + } + else + { + wptr[3] = fptr[3] * 65535.0f; + } + fptr += 4; + wptr += 4; + } + + imageblock_initialize_deriv_from_work_and_orig(pb, pixelcount); +} + + + + +// helper function to initialize the orig-data from the work-data +void imageblock_initialize_orig_from_work(imageblock * pb, int pixelcount) +{ + int i; + float *fptr = pb->orig_data; + float *wptr = pb->work_data; + + for (i = 0; i < pixelcount; i++) + { + if (pb->rgb_lns[i]) + { + fptr[0] = sf16_to_float(lns_to_sf16((uint16_t) wptr[0])); + fptr[1] = sf16_to_float(lns_to_sf16((uint16_t) wptr[1])); + fptr[2] = sf16_to_float(lns_to_sf16((uint16_t) wptr[2])); + } + else + { + fptr[0] = sf16_to_float(unorm16_to_sf16((uint16_t) wptr[0])); + fptr[1] = sf16_to_float(unorm16_to_sf16((uint16_t) wptr[1])); + fptr[2] = sf16_to_float(unorm16_to_sf16((uint16_t) wptr[2])); + } + + if (pb->alpha_lns[i]) + { + fptr[3] = sf16_to_float(lns_to_sf16((uint16_t) wptr[3])); + } + else + { + fptr[3] = sf16_to_float(unorm16_to_sf16((uint16_t) wptr[3])); + } + + fptr += 4; + wptr += 4; + } + + imageblock_initialize_deriv_from_work_and_orig(pb, pixelcount); +} + + + + +// fetch an imageblock from the input file. +void fetch_imageblock(const astc_codec_image * img, imageblock * pb, // picture-block to initialize with image data + // block dimensions + int xdim, int ydim, int zdim, + // position in texture. + int xpos, int ypos, int zpos, swizzlepattern swz) +{ + float *fptr = pb->orig_data; + int xsize = img->xsize + 2 * img->padding; + int ysize = img->ysize + 2 * img->padding; + int zsize = (img->zsize == 1) ? 1 : img->zsize + 2 * img->padding; + + int x, y, z, i; + + pb->xpos = xpos; + pb->ypos = ypos; + pb->zpos = zpos; + + xpos += img->padding; + ypos += img->padding; + if (img->zsize > 1) + zpos += img->padding; + + float data[6]; + data[4] = 0; + data[5] = 1; + + if (img->imagedata8) + { + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int xi = xpos + x; + int yi = ypos + y; + int zi = zpos + z; + // clamp XY coordinates to the picture. + if (xi < 0) + xi = 0; + if (yi < 0) + yi = 0; + if (zi < 0) + zi = 0; + if (xi >= xsize) + xi = xsize - 1; + if (yi >= ysize) + yi = ysize - 1; + if (zi >= zsize) + zi = zsize - 1; + + int r = img->imagedata8[zi][yi][4 * xi]; + int g = img->imagedata8[zi][yi][4 * xi + 1]; + int b = img->imagedata8[zi][yi][4 * xi + 2]; + int a = img->imagedata8[zi][yi][4 * xi + 3]; + + data[0] = r / 255.0f; + data[1] = g / 255.0f; + data[2] = b / 255.0f; + data[3] = a / 255.0f; + + fptr[0] = data[swz.r]; + fptr[1] = data[swz.g]; + fptr[2] = data[swz.b]; + fptr[3] = data[swz.a]; + fptr += 4; + } + } + else if (img->imagedata16) + { + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int xi = xpos + x; + int yi = ypos + y; + int zi = zpos + z; + // clamp XY coordinates to the picture. + if (xi < 0) + xi = 0; + if (yi < 0) + yi = 0; + if (zi < 0) + zi = 0; + if (xi >= xsize) + xi = xsize - 1; + if (yi >= ysize) + yi = ysize - 1; + if (zi >= ysize) + zi = zsize - 1; + + int r = img->imagedata16[zi][yi][4 * xi]; + int g = img->imagedata16[zi][yi][4 * xi + 1]; + int b = img->imagedata16[zi][yi][4 * xi + 2]; + int a = img->imagedata16[zi][yi][4 * xi + 3]; + + float rf = sf16_to_float(r); + float gf = sf16_to_float(g); + float bf = sf16_to_float(b); + float af = sf16_to_float(a); + + // equalize the color components somewhat, and get rid of negative values. + rf = MAX(rf, 1e-8f); + gf = MAX(gf, 1e-8f); + bf = MAX(bf, 1e-8f); + af = MAX(af, 1e-8f); + + + data[0] = rf; + data[1] = gf; + data[2] = bf; + data[3] = af; + + fptr[0] = data[swz.r]; + fptr[1] = data[swz.g]; + fptr[2] = data[swz.b]; + fptr[3] = data[swz.a]; + fptr += 4; + } + } + + + // perform sRGB-to-linear transform on input data, if requested. + int pixelcount = xdim * ydim * zdim; + + if (perform_srgb_transform) + { + fptr = pb->orig_data; + for (i = 0; i < pixelcount; i++) + { + float r = fptr[0]; + float g = fptr[1]; + float b = fptr[2]; + + if (r <= 0.04045f) + r = r * (1.0f / 12.92f); + else if (r <= 1) + r = pow((r + 0.055f) * (1.0f / 1.055f), 2.4f); + + if (g <= 0.04045f) + g = g * (1.0f / 12.92f); + else if (g <= 1) + g = pow((g + 0.055f) * (1.0f / 1.055f), 2.4f); + + if (b <= 0.04045f) + b = b * (1.0f / 12.92f); + else if (b <= 1) + b = pow((b + 0.055f) * (1.0f / 1.055f), 2.4f); + + fptr[0] = r; + fptr[1] = g; + fptr[2] = b; + + fptr += 4; + } + } + + // collect color max-value, in order to determine whether to use LDR or HDR + // interpolation. + float max_red, max_green, max_blue, max_alpha; + max_red = 0.0f; + max_green = 0.0f; + max_blue = 0.0f; + max_alpha = 0.0f; + + fptr = pb->orig_data; + for (i = 0; i < pixelcount; i++) + { + float r = fptr[0]; + float g = fptr[1]; + float b = fptr[2]; + float a = fptr[3]; + + if (r > max_red) + max_red = r; + if (g > max_green) + max_green = g; + if (b > max_blue) + max_blue = b; + if (a > max_alpha) + max_alpha = a; + + fptr += 4; + } + + float max_rgb = MAX(max_red, MAX(max_green, max_blue)); + + // use LNS if: + // * RGB-maximum is less than 0.15 + // * RGB-maximum is greater than 1 + // * Alpha-maximum is greater than 1 + int rgb_lns = (max_rgb < 0.15f || max_rgb > 1.0f || max_alpha > 1.0f) ? 1 : 0; + int alpha_lns = rgb_lns ? (max_alpha > 1.0f || max_alpha < 0.15f) : 0; + + // not yet though; for the time being, just obey the command line. + rgb_lns = rgb_force_use_of_hdr; + alpha_lns = alpha_force_use_of_hdr; + + // impose the choice on every pixel when encoding. + for (i = 0; i < pixelcount; i++) + { + pb->rgb_lns[i] = rgb_lns; + pb->alpha_lns[i] = alpha_lns; + pb->nan_texel[i] = 0; + } + + + imageblock_initialize_work_from_orig(pb, pixelcount); + + + update_imageblock_flags(pb, xdim, ydim, zdim); +} + + + + +void write_imageblock(astc_codec_image * img, const imageblock * pb, // picture-block to initialize with image data. We assume that orig_data is valid. + // block dimensions + int xdim, int ydim, int zdim, + // position to write the block to + int xpos, int ypos, int zpos, swizzlepattern swz) +{ + const float *fptr = pb->orig_data; + const uint8_t *nptr = pb->nan_texel; + int xsize = img->xsize; + int ysize = img->ysize; + int zsize = img->zsize; + int x, y, z; + + + float data[7]; + data[4] = 0.0f; + data[5] = 1.0f; + + + if (img->imagedata8) + { + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int xi = xpos + x; + int yi = ypos + y; + int zi = zpos + z; + + if (xi >= 0 && yi >= 0 && zi >= 0 && xi < xsize && yi < ysize && zi < zsize) + { + if (*nptr) + { + // NaN-pixel, but we can't display it. Display purple instead. + img->imagedata8[zi][yi][4 * xi] = 0xFF; + img->imagedata8[zi][yi][4 * xi + 1] = 0x00; + img->imagedata8[zi][yi][4 * xi + 2] = 0xFF; + img->imagedata8[zi][yi][4 * xi + 3] = 0xFF; + } + + else + { + // apply swizzle + if (perform_srgb_transform) + { + float r = fptr[0]; + float g = fptr[1]; + float b = fptr[2]; + + if (r <= 0.0031308f) + r = r * 12.92f; + else if (r <= 1) + r = 1.055f * pow(r, (1.0f / 2.4f)) - 0.055f; + + if (g <= 0.0031308f) + g = g * 12.92f; + else if (g <= 1) + g = 1.055f * pow(g, (1.0f / 2.4f)) - 0.055f; + + if (b <= 0.0031308f) + b = b * 12.92f; + else if (b <= 1) + b = 1.055f * pow(b, (1.0f / 2.4f)) - 0.055f; + + data[0] = r; + data[1] = g; + data[2] = b; + } + else + { + float r = fptr[0]; + float g = fptr[1]; + float b = fptr[2]; + + data[0] = r; + data[1] = g; + data[2] = b; + } + data[3] = fptr[3]; + + + + + float xcoord = (data[0] * 2.0f) - 1.0f; + float ycoord = (data[3] * 2.0f) - 1.0f; + float zcoord = 1.0f - xcoord * xcoord - ycoord * ycoord; + if (zcoord < 0.0f) + zcoord = 0.0f; + data[6] = (sqrt(zcoord) * 0.5f) + 0.5f; + + // clamp to [0,1] + if (data[0] > 1.0f) + data[0] = 1.0f; + if (data[1] > 1.0f) + data[1] = 1.0f; + if (data[2] > 1.0f) + data[2] = 1.0f; + if (data[3] > 1.0f) + data[3] = 1.0f; + + + // pack the data + int ri = static_cast < int >(floor(data[swz.r] * 255.0f + 0.5f)); + int gi = static_cast < int >(floor(data[swz.g] * 255.0f + 0.5f)); + int bi = static_cast < int >(floor(data[swz.b] * 255.0f + 0.5f)); + int ai = static_cast < int >(floor(data[swz.a] * 255.0f + 0.5f)); + + img->imagedata8[zi][yi][4 * xi] = ri; + img->imagedata8[zi][yi][4 * xi + 1] = gi; + img->imagedata8[zi][yi][4 * xi + 2] = bi; + img->imagedata8[zi][yi][4 * xi + 3] = ai; + } + } + fptr += 4; + nptr++; + } + } + else if (img->imagedata16) + { + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + int xi = xpos + x; + int yi = ypos + y; + int zi = zpos + z; + + if (xi >= 0 && yi >= 0 && zi >= 0 && xi < xsize && yi < ysize && zi < zsize) + { + if (*nptr) + { + img->imagedata16[zi][yi][4 * xi] = 0xFFFF; + img->imagedata16[zi][yi][4 * xi + 1] = 0xFFFF; + img->imagedata16[zi][yi][4 * xi + 2] = 0xFFFF; + img->imagedata16[zi][yi][4 * xi + 3] = 0xFFFF; + } + + else + { + // apply swizzle + if (perform_srgb_transform) + { + float r = fptr[0]; + float g = fptr[1]; + float b = fptr[2]; + + if (r <= 0.0031308f) + r = r * 12.92f; + else if (r <= 1) + r = 1.055f * pow(r, (1.0f / 2.4f)) - 0.055f; + if (g <= 0.0031308f) + g = g * 12.92f; + else if (g <= 1) + g = 1.055f * pow(g, (1.0f / 2.4f)) - 0.055f; + if (b <= 0.0031308f) + b = b * 12.92f; + else if (b <= 1) + b = 1.055f * pow(b, (1.0f / 2.4f)) - 0.055f; + + data[0] = r; + data[1] = g; + data[2] = b; + } + else + { + data[0] = fptr[0]; + data[1] = fptr[1]; + data[2] = fptr[2]; + } + data[3] = fptr[3]; + + float x = (data[0] * 2.0f) - 1.0f; + float y = (data[3] * 2.0f) - 1.0f; + float z = 1.0f - x * x - y * y; + if (z < 0.0f) + z = 0.0f; + data[6] = (sqrt(z) * 0.5f) + 0.5f; + + + int r = float_to_sf16(data[swz.r], SF_NEARESTEVEN); + int g = float_to_sf16(data[swz.g], SF_NEARESTEVEN); + int b = float_to_sf16(data[swz.b], SF_NEARESTEVEN); + int a = float_to_sf16(data[swz.a], SF_NEARESTEVEN); + img->imagedata16[zi][yi][4 * xi] = r; + img->imagedata16[zi][yi][4 * xi + 1] = g; + img->imagedata16[zi][yi][4 * xi + 2] = b; + img->imagedata16[zi][yi][4 * xi + 3] = a; + } + } + fptr += 4; + nptr++; + } + } +} + + + +/* + For an imageblock, update its flags. + + The updating is done based on work_data, not orig_data. +*/ +void update_imageblock_flags(imageblock * pb, int xdim, int ydim, int zdim) +{ + int i; + float red_min = 1e38f, red_max = -1e38f; + float green_min = 1e38f, green_max = -1e38f; + float blue_min = 1e38f, blue_max = -1e38f; + float alpha_min = 1e38f, alpha_max = -1e38f; + + int texels_per_block = xdim * ydim * zdim; + + int grayscale = 1; + + for (i = 0; i < texels_per_block; i++) + { + float red = pb->work_data[4 * i]; + float green = pb->work_data[4 * i + 1]; + float blue = pb->work_data[4 * i + 2]; + float alpha = pb->work_data[4 * i + 3]; + if (red < red_min) + red_min = red; + if (red > red_max) + red_max = red; + if (green < green_min) + green_min = green; + if (green > green_max) + green_max = green; + if (blue < blue_min) + blue_min = blue; + if (blue > blue_max) + blue_max = blue; + if (alpha < alpha_min) + alpha_min = alpha; + if (alpha > alpha_max) + alpha_max = alpha; + + if (grayscale == 1 && (red != green || red != blue)) + grayscale = 0; + } + + pb->red_min = red_min; + pb->red_max = red_max; + pb->green_min = green_min; + pb->green_max = green_max; + pb->blue_min = blue_min; + pb->blue_max = blue_max; + pb->alpha_min = alpha_min; + pb->alpha_max = alpha_max; + pb->grayscale = grayscale; +} + + +// Helper functions for various error-metric calculations + +double clampx(double p) +{ + if (astc_isnan(p) || p < 0.0f) + p = 0.0f; + else if (p > 65504.0f) + p = 65504.0f; + return p; +} + +// logarithm-function, linearized from 2^-14. +double xlog2(double p) +{ + if (p >= 0.00006103515625) + return log(p) * 1.44269504088896340735; // log(x)/log(2) + else + return -15.44269504088896340735 + p * 23637.11554992477646609062; +} + + +// mPSNR tone-mapping operator +double mpsnr_operator(double v, int fstop) +{ + int64_t vl = 1LL << (fstop + 32); + double vl2 = (double)vl * (1.0 / 4294967296.0); + v *= vl2; + v = pow(v, (1.0 / 2.2)); + v *= 255.0f; + if (astc_isnan(v) || v < 0.0f) + v = 0.0f; + else if (v > 255.0f) + v = 255.0f; + return v; +} + + +double mpsnr_sumdiff(double v1, double v2, int low_fstop, int high_fstop) +{ + int i; + double summa = 0.0; + for (i = low_fstop; i <= high_fstop; i++) + { + double mv1 = mpsnr_operator(v1, i); + double mv2 = mpsnr_operator(v2, i); + double mdiff = mv1 - mv2; + summa += mdiff * mdiff; + } + return summa; +} + + + + +// Compute PSNR and other error metrics between input and output image +void compute_error_metrics(int compute_hdr_error_metrics, int input_components, const astc_codec_image * img1, const astc_codec_image * img2, int low_fstop, int high_fstop, int psnrmode) +{ + int x, y, z; + static int channelmasks[5] = { 0x00, 0x07, 0x0C, 0x07, 0x0F }; + int channelmask; + + channelmask = channelmasks[input_components]; + + + double4 errorsum = double4(0, 0, 0, 0); + double4 alpha_scaled_errorsum = double4(0, 0, 0, 0); + double4 log_errorsum = double4(0, 0, 0, 0); + double4 mpsnr_errorsum = double4(0, 0, 0, 0); + + int xsize = MIN(img1->xsize, img2->xsize); + int ysize = MIN(img1->ysize, img2->ysize); + int zsize = MIN(img1->zsize, img2->zsize); + + if (img1->xsize != img2->xsize || img1->ysize != img2->ysize || img1->zsize != img2->zsize) + { + printf("Warning: comparing images of different size:\n" + "Image 1: %dx%dx%d\n" "Image 2: %dx%dx%d\n" "Only intersection region will be compared.\n", img1->xsize, img1->ysize, img1->zsize, img2->xsize, img2->ysize, img2->zsize); + } + + if (compute_hdr_error_metrics) + { + printf("Computing error metrics ... "); + fflush(stdout); + } + + int img1pad = img1->padding; + int img2pad = img2->padding; + + double rgb_peak = 0.0f; + + for (z = 0; z < zsize; z++) + for (y = 0; y < ysize; y++) + { + int ze1 = (img1->zsize == 1) ? z : z + img1pad; + int ze2 = (img2->zsize == 1) ? z : z + img2pad; + + int ye1 = y + img1pad; + int ye2 = y + img2pad; + + for (x = 0; x < xsize; x++) + { + double4 input_color1; + double4 input_color2; + + int xe1 = 4 * x + 4 * img1pad; + int xe2 = 4 * x + 4 * img2pad; + + if (img1->imagedata8) + { + input_color1 = + double4(img1->imagedata8[ze1][ye1][xe1] * (1.0f / 255.0f), + img1->imagedata8[ze1][ye1][xe1 + 1] * (1.0f / 255.0f), img1->imagedata8[ze1][ye1][xe1 + 2] * (1.0f / 255.0f), img1->imagedata8[ze1][ye1][xe1 + 3] * (1.0f / 255.0f)); + } + else + { + input_color1 = + double4(clampx(sf16_to_float(img1->imagedata16[ze1][ye1][xe1])), + clampx(sf16_to_float(img1->imagedata16[ze1][ye1][xe1 + 1])), + clampx(sf16_to_float(img1->imagedata16[ze1][ye1][xe1 + 2])), clampx(sf16_to_float(img1->imagedata16[ze1][ye1][xe1 + 3]))); + } + + if (img2->imagedata8) + { + input_color2 = + double4(img2->imagedata8[ze2][ye2][xe2] * (1.0f / 255.0f), + img2->imagedata8[ze2][ye2][xe2 + 1] * (1.0f / 255.0f), img2->imagedata8[ze2][ye2][xe2 + 2] * (1.0f / 255.0f), img2->imagedata8[ze2][ye2][xe2 + 3] * (1.0f / 255.0f)); + } + else + { + input_color2 = + double4(clampx(sf16_to_float(img2->imagedata16[ze2][ye2][xe2])), + clampx(sf16_to_float(img2->imagedata16[ze2][ye2][xe2 + 1])), + clampx(sf16_to_float(img2->imagedata16[ze2][ye2][xe2 + 2])), clampx(sf16_to_float(img2->imagedata16[ze2][ye2][xe2 + 3]))); + } + + rgb_peak = MAX(MAX(input_color1.x, input_color1.y), MAX(input_color1.z, rgb_peak)); + + double4 diffcolor = input_color1 - input_color2; + errorsum = errorsum + diffcolor * diffcolor; + + double4 alpha_scaled_diffcolor = double4(diffcolor.xyz * input_color1.w, diffcolor.w); + alpha_scaled_errorsum = alpha_scaled_errorsum + alpha_scaled_diffcolor * alpha_scaled_diffcolor; + + if (compute_hdr_error_metrics) + { + double4 log_input_color1 = double4(xlog2(input_color1.x), + xlog2(input_color1.y), + xlog2(input_color1.z), + xlog2(input_color1.w)); + + double4 log_input_color2 = double4(xlog2(input_color2.x), + xlog2(input_color2.y), + xlog2(input_color2.z), + xlog2(input_color2.w)); + + double4 log_diffcolor = log_input_color1 - log_input_color2; + + log_errorsum = log_errorsum + log_diffcolor * log_diffcolor; + + double4 mpsnr_error = double4(mpsnr_sumdiff(input_color1.x, input_color2.x, low_fstop, high_fstop), + mpsnr_sumdiff(input_color1.y, input_color2.y, low_fstop, high_fstop), + mpsnr_sumdiff(input_color1.z, input_color2.z, low_fstop, high_fstop), + mpsnr_sumdiff(input_color1.w, input_color2.w, low_fstop, high_fstop)); + mpsnr_errorsum = mpsnr_errorsum + mpsnr_error; + } + } + } + + if (compute_hdr_error_metrics) + { + printf("done\n"); + } + + double pixels = xsize * ysize * zsize; + + double num = 0.0; + double alpha_num = 0.0; + double log_num = 0.0; + double mpsnr_num = 0.0; + double samples = 0.0; + + if (channelmask & 1) + { + num += errorsum.x; + alpha_num += alpha_scaled_errorsum.x; + log_num += log_errorsum.x; + mpsnr_num += mpsnr_errorsum.x; + samples += pixels; + } + if (channelmask & 2) + { + num += errorsum.y; + alpha_num += alpha_scaled_errorsum.y; + log_num += log_errorsum.y; + mpsnr_num += mpsnr_errorsum.y; + samples += pixels; + } + if (channelmask & 4) + { + num += errorsum.z; + alpha_num += alpha_scaled_errorsum.z; + log_num += log_errorsum.z; + mpsnr_num += mpsnr_errorsum.z; + samples += pixels; + } + if (channelmask & 8) + { + num += errorsum.w; + alpha_num += alpha_scaled_errorsum.w; /* log_num += log_errorsum.w; mpsnr_num += mpsnr_errorsum.w; */ + samples += pixels; + } + + double denom = samples; + double mpsnr_denom = pixels * 3.0 * (high_fstop - low_fstop + 1) * 255.0f * 255.0f; + + double psnr; + if (num == 0) + psnr = 999.0; + else + psnr = 10.0 * log10((double)denom / (double)num); + + double rgb_psnr = psnr; + + if(psnrmode == 1) + { + if (channelmask & 8) + { + printf("PSNR (LDR-RGBA): %.6lf dB\n", psnr); + + double alpha_psnr; + if (alpha_num == 0) + alpha_psnr = 999.0; + else + alpha_psnr = 10.0 * log10((double)denom / (double)alpha_num); + printf("Alpha-Weighted PSNR: %.6lf dB\n", alpha_psnr); + + double rgb_num = errorsum.x + errorsum.y + errorsum.z; + if (rgb_num == 0) + rgb_psnr = 999.0; + else + rgb_psnr = 10.0 * log10((double)pixels * 3 / (double)rgb_num); + printf("PSNR (LDR-RGB): %.6lf dB\n", rgb_psnr); + } + else + printf("PSNR (LDR-RGB): %.6lf dB\n", psnr); + + + if (compute_hdr_error_metrics) + { + printf("Color peak value: %f\n", rgb_peak); + printf("PSNR (RGB normalized to peak): %f dB\n", rgb_psnr + 20.0 * log10(rgb_peak)); + + double mpsnr; + if (mpsnr_num == 0) + mpsnr = 999.0; + else + mpsnr = 10.0 * log10((double)mpsnr_denom / (double)mpsnr_num); + printf("mPSNR (RGB) [fstops: %+d to %+d] : %.6lf dB\n", low_fstop, high_fstop, mpsnr); + + double logrmse = sqrt((double)log_num / (double)pixels); + printf("LogRMSE (RGB): %.6lf\n", logrmse); + } + } +} + +/* + Main image loader function. + + We have specialized loaders for DDS, KTX and HTGA; for other formats, we use stb_image. + This image loader will choose one based on filename. +*/ + + + +astc_codec_image *astc_codec_load_image(const char *input_filename, int padding, int *load_result) +{ + #define LOAD_HTGA 0 + #define LOAD_KTX 1 + #define LOAD_DDS 2 + #define LOAD_STB_IMAGE 3 + + // check the ending of the input filename + int load_fileformat = LOAD_STB_IMAGE; + int filename_len = strlen(input_filename); + + const char *eptr = input_filename + filename_len - 5; + if (eptr > input_filename && (strcmp(eptr, ".htga") == 0 || strcmp(eptr, ".HTGA") == 0)) + load_fileformat = LOAD_HTGA; + eptr = input_filename + filename_len - 4; + if (eptr > input_filename && (strcmp(eptr, ".ktx") == 0 || strcmp(eptr, ".KTX") == 0)) + load_fileformat = LOAD_KTX; + if (eptr > input_filename && (strcmp(eptr, ".dds") == 0 || strcmp(eptr, ".DDS") == 0)) + load_fileformat = LOAD_DDS; + + // OpenEXR support: call exr_to_htga to convert from EXR to HTGA. + char htga_load_filename[300]; + int load_exr = 0; + if (eptr > input_filename && (strcmp(eptr, ".exr") == 0 || strcmp(eptr, ".EXR") == 0)) + { + // don't support filenames longer than 250 characters; this way, we + // cannot get a buffer overflow from the sprintfs below. + if (filename_len > 250) + { + *load_result = -1; + return NULL; + } + + char exr_to_htga_command[550]; + sprintf(htga_load_filename, "%s.htga", input_filename); + sprintf(exr_to_htga_command, "exr_to_htga -q %s %s", input_filename, htga_load_filename); + + int retval = system(exr_to_htga_command); + if (retval != 0) + { + printf("Failed to run exr_to_htga to convert input .exr file.\n"); + exit(1); + } + input_filename = htga_load_filename; + load_fileformat = LOAD_HTGA; + load_exr = 1; + } + + astc_codec_image *input_image; + + switch (load_fileformat) + { + case LOAD_KTX: + input_image = load_ktx_uncompressed_image(input_filename, padding, load_result); + break; + case LOAD_DDS: + input_image = load_dds_uncompressed_image(input_filename, padding, load_result); + break; + case LOAD_HTGA: + input_image = load_tga_image(input_filename, padding, load_result); + break; + case LOAD_STB_IMAGE: + input_image = load_image_with_stb(input_filename, padding, load_result); + break; + default: + ASTC_CODEC_INTERNAL_ERROR; + exit(1); + } + + if (load_exr) + astc_codec_unlink(htga_load_filename); + + return input_image; +} + + + + +int get_output_filename_enforced_bitness(const char *output_filename) +{ + if (output_filename == NULL) + return -1; + + int filename_len = strlen(output_filename); + const char *eptr = output_filename + filename_len - 5; + + if (eptr > output_filename && (strcmp(eptr, ".htga") == 0 || strcmp(eptr, ".HTGA") == 0)) + { + return 16; + } + + eptr = output_filename + filename_len - 4; + if (eptr > output_filename && (strcmp(eptr, ".tga") == 0 || strcmp(eptr, ".TGA") == 0)) + { + return 8; + } + if (eptr > output_filename && (strcmp(eptr, ".exr") == 0 || strcmp(eptr, ".EXR") == 0)) + { + return 16; + } + + // file formats that don't match any of the templates above are capable of accommodating + // both 8-bit and 16-bit data (DDS, KTX) + return -1; +} + + + + +int astc_codec_store_image(const astc_codec_image * output_image, const char *output_filename, int bitness, const char **format_string) +{ + #define STORE_TGA 0 + #define STORE_HTGA 1 + #define STORE_KTX 2 + #define STORE_DDS 3 + #define STORE_EXR 4 + + int filename_len = strlen(output_filename); + + int store_fileformat = STORE_TGA; + const char *eptr = output_filename + filename_len - 5; + if (eptr > output_filename && (strcmp(eptr, ".htga") == 0 || strcmp(eptr, ".HTGA") == 0)) + { + store_fileformat = STORE_HTGA; + } + eptr = output_filename + filename_len - 4; + if (eptr > output_filename && (strcmp(eptr, ".ktx") == 0 || strcmp(eptr, ".KTX") == 0)) + { + store_fileformat = STORE_KTX; + } + if (eptr > output_filename && (strcmp(eptr, ".dds") == 0 || strcmp(eptr, ".DDS") == 0)) + { + store_fileformat = STORE_DDS; + } + if (eptr > output_filename && (strcmp(eptr, ".exr") == 0 || strcmp(eptr, ".EXR") == 0)) + { + store_fileformat = STORE_EXR; + } + + if (store_fileformat == STORE_TGA && bitness == 16) + store_fileformat = STORE_HTGA; + + // guard against OpenEXR files with too-long names + if (store_fileformat == STORE_EXR && filename_len > 250) + { + *format_string = "EXR"; + return -1; + } + + + char htga_output_filename[300]; + char htga_output_command[550]; + int system_retval; + + int store_result = -1; + switch (store_fileformat) + { + case STORE_TGA: + case STORE_HTGA: + *format_string = bitness == 16 ? "HTGA" : "TGA"; + store_result = store_tga_image(output_image, output_filename, bitness); + break; + case STORE_KTX: + *format_string = "KTX"; + store_result = store_ktx_uncompressed_image(output_image, output_filename, bitness); + break; + case STORE_DDS: + *format_string = "DDS"; + store_result = store_dds_uncompressed_image(output_image, output_filename, bitness); + break; + + case STORE_EXR: + *format_string = "EXR"; + sprintf(htga_output_filename, "%s.htga", output_filename); + store_result = store_tga_image(output_image, htga_output_filename, 16); + sprintf(htga_output_command, "exr_to_htga -e %s %s", htga_output_filename, output_filename); + system_retval = system(htga_output_command); + astc_codec_unlink(htga_output_filename); + if (system_retval != 0) + store_result = -99; + break; + + default: + ASTC_CODEC_INTERNAL_ERROR; + exit(1); + break; + }; + + return store_result; +} diff --git a/third_party/astcenc/Source/astc_integer_sequence.cpp b/third_party/astcenc/Source/astc_integer_sequence.cpp new file mode 100644 index 0000000000..58c706a96d --- /dev/null +++ b/third_party/astcenc/Source/astc_integer_sequence.cpp @@ -0,0 +1,649 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions to encode/decode data using Bounded Integer Sequence + * Encoding. + */ +/*----------------------------------------------------------------------------*/ +#include "astc_codec_internals.h" + // unpacked quint triplets for each packed-quint value +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}, +}; + +// packed quint-value for every unpacked quint-triplet +// indexed by [high][middle][low] +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,}, + }, +}; + +// unpacked trit quintuplets for each packed-quint value +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}, +}; + +// packed trit-value for every unpacked trit-quintuplet +// indexed by [high][][][][low] +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,}, + }, + }, + }, +}; + + + +void find_number_of_bits_trits_quints(int quantization_level, int *bits, int *trits, int *quints) +{ + *bits = 0; + *trits = 0; + *quints = 0; + switch (quantization_level) + { + case QUANT_2: + *bits = 1; + break; + case QUANT_3: + *bits = 0; + *trits = 1; + break; + case QUANT_4: + *bits = 2; + break; + case QUANT_5: + *bits = 0; + *quints = 1; + break; + case QUANT_6: + *bits = 1; + *trits = 1; + break; + case QUANT_8: + *bits = 3; + break; + case QUANT_10: + *bits = 1; + *quints = 1; + break; + case QUANT_12: + *bits = 2; + *trits = 1; + break; + case QUANT_16: + *bits = 4; + break; + case QUANT_20: + *bits = 2; + *quints = 1; + break; + case QUANT_24: + *bits = 3; + *trits = 1; + break; + case QUANT_32: + *bits = 5; + break; + case QUANT_40: + *bits = 3; + *quints = 1; + break; + case QUANT_48: + *bits = 4; + *trits = 1; + break; + case QUANT_64: + *bits = 6; + break; + case QUANT_80: + *bits = 4; + *quints = 1; + break; + case QUANT_96: + *bits = 5; + *trits = 1; + break; + case QUANT_128: + *bits = 7; + break; + case QUANT_160: + *bits = 5; + *quints = 1; + break; + case QUANT_192: + *bits = 6; + *trits = 1; + break; + case QUANT_256: + *bits = 8; + break; + } +} + + +// routine to write up to 8 bits +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; +} + + +// routine to read up to 8 bits +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; +} + + + + +void encode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset) +{ + int i; + uint8_t lowparts[64]; + uint8_t highparts[69]; // 64 elements + 5 elements for padding + uint8_t tq_blocks[22]; // trit-blocks or quint-blocks + + int bits, trits, quints; + find_number_of_bits_trits_quints(quantization_level, &bits, &trits, &quints); + + for (i = 0; i < elements; i++) + { + lowparts[i] = input_data[i] & ((1 << bits) - 1); + highparts[i] = input_data[i] >> bits; + } + for (i = elements; i < elements + 5; i++) + highparts[i] = 0; // padding before we start constructing trit-blocks or quint-blocks + + // construct trit-blocks or quint-blocks as necessary + if (trits) + { + int trit_blocks = (elements + 4) / 5; + for (i = 0; i < trit_blocks; i++) + tq_blocks[i] = integer_of_trits[highparts[5 * i + 4]][highparts[5 * i + 3]][highparts[5 * i + 2]][highparts[5 * i + 1]][highparts[5 * i]]; + } + if (quints) + { + int quint_blocks = (elements + 2) / 3; + for (i = 0; i < quint_blocks; i++) + tq_blocks[i] = integer_of_quints[highparts[3 * i + 2]][highparts[3 * i + 1]][highparts[3 * i]]; + } + + // then, write out the actual bits. + int lcounter = 0; + int hcounter = 0; + for (i = 0; i < elements; i++) + { + write_bits(lowparts[i], bits, bit_offset, output_data); + bit_offset += bits; + if (trits) + { + static const int bits_to_write[5] = { 2, 2, 1, 2, 1 }; + static const int block_shift[5] = { 0, 2, 4, 5, 7 }; + static const int next_lcounter[5] = { 1, 2, 3, 4, 0 }; + static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 }; + write_bits(tq_blocks[hcounter] >> block_shift[lcounter], bits_to_write[lcounter], bit_offset, output_data); + bit_offset += bits_to_write[lcounter]; + hcounter += hcounter_incr[lcounter]; + lcounter = next_lcounter[lcounter]; + } + if (quints) + { + static const int bits_to_write[3] = { 3, 2, 2 }; + static const int block_shift[3] = { 0, 3, 5 }; + static const int next_lcounter[3] = { 1, 2, 0 }; + static const int hcounter_incr[3] = { 0, 0, 1 }; + write_bits(tq_blocks[hcounter] >> block_shift[lcounter], bits_to_write[lcounter], bit_offset, output_data); + bit_offset += bits_to_write[lcounter]; + hcounter += hcounter_incr[lcounter]; + lcounter = next_lcounter[lcounter]; + } + } +} + + + + +void decode_ise(int quantization_level, int elements, const uint8_t * input_data, uint8_t * output_data, int bit_offset) +{ + int i; + // 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 elements + // of padding. + uint8_t results[68]; + uint8_t tq_blocks[22]; // trit-blocks or quint-blocks + + int bits, trits, quints; + find_number_of_bits_trits_quints(quantization_level, &bits, &trits, &quints); + + int lcounter = 0; + int hcounter = 0; + + // trit-blocks or quint-blocks must be zeroed out before we collect them in the loop below. + for (i = 0; i < 22; i++) + tq_blocks[i] = 0; + + // collect bits for each element, as well as bits for any trit-blocks and quint-blocks. + for (i = 0; i < elements; i++) + { + results[i] = read_bits(bits, bit_offset, input_data); + bit_offset += bits; + if (trits) + { + static const int bits_to_read[5] = { 2, 2, 1, 2, 1 }; + static const int block_shift[5] = { 0, 2, 4, 5, 7 }; + static const int next_lcounter[5] = { 1, 2, 3, 4, 0 }; + static const int hcounter_incr[5] = { 0, 0, 0, 0, 1 }; + 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 int bits_to_read[3] = { 3, 2, 2 }; + static const int block_shift[3] = { 0, 3, 5 }; + static const int next_lcounter[3] = { 1, 2, 0 }; + static const int hcounter_incr[3] = { 0, 0, 1 }; + 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) + { + int trit_blocks = (elements + 4) / 5; + for (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) + { + int quint_blocks = (elements + 2) / 3; + for (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 (i = 0; i < elements; i++) + output_data[i] = results[i]; +} + + + + +int compute_ise_bitcount(int items, quantization_method quant) +{ + switch (quant) + { + case QUANT_2: + return items; + case QUANT_3: + return (8 * items + 4) / 5; + case QUANT_4: + return 2 * items; + case QUANT_5: + return (7 * items + 2) / 3; + case QUANT_6: + return (13 * items + 4) / 5; + case QUANT_8: + return 3 * items; + case QUANT_10: + return (10 * items + 2) / 3; + case QUANT_12: + return (18 * items + 4) / 5; + case QUANT_16: + return items * 4; + case QUANT_20: + return (13 * items + 2) / 3; + case QUANT_24: + return (23 * items + 4) / 5; + case QUANT_32: + return 5 * items; + case QUANT_40: + return (16 * items + 2) / 3; + case QUANT_48: + return (28 * items + 4) / 5; + case QUANT_64: + return 6 * items; + case QUANT_80: + return (19 * items + 2) / 3; + case QUANT_96: + return (33 * items + 4) / 5; + case QUANT_128: + return 7 * items; + case QUANT_160: + return (22 * items + 2) / 3; + case QUANT_192: + return (38 * items + 4) / 5; + case QUANT_256: + return 8 * items; + default: + return 100000; + } +} diff --git a/third_party/astcenc/Source/astc_kmeans_partitioning.cpp b/third_party/astcenc/Source/astc_kmeans_partitioning.cpp new file mode 100644 index 0000000000..13fd4abc40 --- /dev/null +++ b/third_party/astcenc/Source/astc_kmeans_partitioning.cpp @@ -0,0 +1,520 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief approximate k-means cluster partitioning. Do this in 2 stages + * + * 1: basic clustering, a couple of passes just to get a few clusters + * 2: clustering based on line, a few passes until it seems to + * stabilize. + * + * After clustering is done, we use the clustering result to construct + * one bitmap for each partition. We then scan though the partition table, + * counting how well the bitmaps matched. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +// for k++ means, we need pseudo-random numbers, however using random numbers directly +// results in irreproducible encoding results. As such, we will instead +// just supply a handful of numbers from random.org, and apply an algorithm similar +// to XKCD #221. (http://xkcd.com/221/) +// cluster the texels using the k++ means clustering initialization algorithm. + +void kpp_initialize(int xdim, int ydim, int zdim, int partition_count, const imageblock * blk, float4 * cluster_centers) +{ + int i; + + int texels_per_block = xdim * ydim * zdim; + + int cluster_center_samples[4]; + // pick a random sample as first center-point. + cluster_center_samples[0] = 145897 /* number from random.org */ % texels_per_block; + int samples_selected = 1; + + float distances[MAX_TEXELS_PER_BLOCK]; + + // compute the distance to the first point. + int sample = cluster_center_samples[0]; + float4 center_color = float4(blk->work_data[4 * sample], + blk->work_data[4 * sample + 1], + blk->work_data[4 * sample + 2], + blk->work_data[4 * sample + 3]); + + float distance_sum = 0.0f; + for (i = 0; i < texels_per_block; i++) + { + float4 color = float4(blk->work_data[4 * i], + blk->work_data[4 * i + 1], + blk->work_data[4 * i + 2], + blk->work_data[4 * i + 3]); + float4 diff = color - center_color; + float distance = dot(diff, diff); + distance_sum += distance; + distances[i] = distance; + } + + // more numbers from random.org + float cluster_cutoffs[25] = { + 0.952312f, 0.206893f, 0.835984f, 0.507813f, 0.466170f, + 0.872331f, 0.488028f, 0.866394f, 0.363093f, 0.467905f, + 0.812967f, 0.626220f, 0.932770f, 0.275454f, 0.832020f, + 0.362217f, 0.318558f, 0.240113f, 0.009190f, 0.983995f, + 0.566812f, 0.347661f, 0.731960f, 0.156391f, 0.297786f + }; + + while (1) + { + // pick a point in a weighted-random fashion. + float summa = 0.0f; + float distance_cutoff = distance_sum * cluster_cutoffs[samples_selected + 5 * partition_count]; + for (i = 0; i < texels_per_block; i++) + { + summa += distances[i]; + if (summa >= distance_cutoff) + break; + } + sample = i; + if (sample >= texels_per_block) + sample = texels_per_block - 1; + + + cluster_center_samples[samples_selected] = sample; + samples_selected++; + if (samples_selected >= partition_count) + break; + + // update the distances with the new point. + center_color = float4(blk->work_data[4 * sample], blk->work_data[4 * sample + 1], blk->work_data[4 * sample + 2], blk->work_data[4 * sample + 3]); + + distance_sum = 0.0f; + for (i = 0; i < texels_per_block; i++) + { + float4 color = float4(blk->work_data[4 * i], + blk->work_data[4 * i + 1], + blk->work_data[4 * i + 2], + blk->work_data[4 * i + 3]); + float4 diff = color - center_color; + float distance = dot(diff, diff); + distance = MIN(distance, distances[i]); + distance_sum += distance; + distances[i] = distance; + } + } + + // finally, gather up the results. + for (i = 0; i < partition_count; i++) + { + int sample = cluster_center_samples[i]; + float4 color = float4(blk->work_data[4 * sample], + blk->work_data[4 * sample + 1], + blk->work_data[4 * sample + 2], + blk->work_data[4 * sample + 3]); + cluster_centers[i] = color; + } +} + + +// basic K-means clustering: given a set of cluster centers, +// assign each texel to a partition +void basic_kmeans_assign_pass(int xdim, int ydim, int zdim, int partition_count, const imageblock * blk, const float4 * cluster_centers, int *partition_of_texel) +{ + int i, j; + + int texels_per_block = xdim * ydim * zdim; + + float distances[MAX_TEXELS_PER_BLOCK]; + float4 center_color = cluster_centers[0]; + + int texels_per_partition[4]; + + texels_per_partition[0] = texels_per_block; + for (i = 1; i < partition_count; i++) + texels_per_partition[i] = 0; + + + for (i = 0; i < texels_per_block; i++) + { + float4 color = float4(blk->work_data[4 * i], + blk->work_data[4 * i + 1], + blk->work_data[4 * i + 2], + blk->work_data[4 * i + 3]); + float4 diff = color - center_color; + float distance = dot(diff, diff); + distances[i] = distance; + partition_of_texel[i] = 0; + } + + + + for (j = 1; j < partition_count; j++) + { + float4 center_color = cluster_centers[j]; + + for (i = 0; i < texels_per_block; i++) + { + float4 color = float4(blk->work_data[4 * i], + blk->work_data[4 * i + 1], + blk->work_data[4 * i + 2], + blk->work_data[4 * i + 3]); + float4 diff = color - center_color; + float distance = dot(diff, diff); + if (distance < distances[i]) + { + distances[i] = distance; + texels_per_partition[partition_of_texel[i]]--; + texels_per_partition[j]++; + partition_of_texel[i] = j; + } + } + } + + // it is possible to get a situation where one of the partitions ends up + // without any texels. In this case, we 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, we run the whole loop over again. + int problem_case; + do + { + problem_case = 0; + for (i = 0; i < partition_count; i++) + { + if (texels_per_partition[i] == 0) + { + texels_per_partition[partition_of_texel[i]]--; + texels_per_partition[i]++; + partition_of_texel[i] = i; + problem_case = 1; + } + } + } + while (problem_case != 0); + +} + + +// basic k-means clustering: given a set of cluster assignments +// for the texels, find the center position of each cluster. +void basic_kmeans_update(int xdim, int ydim, int zdim, int partition_count, const imageblock * blk, const int *partition_of_texel, float4 * cluster_centers) +{ + int i; + + int texels_per_block = xdim * ydim * zdim; + + float4 color_sum[4]; + int weight_sum[4]; + + for (i = 0; i < partition_count; i++) + { + color_sum[i] = float4(0, 0, 0, 0); + weight_sum[i] = 0; + } + + + // first, find the center-of-gravity in each cluster + for (i = 0; i < texels_per_block; i++) + { + float4 color = float4(blk->work_data[4 * i], + blk->work_data[4 * i + 1], + blk->work_data[4 * i + 2], + blk->work_data[4 * i + 3]); + int part = partition_of_texel[i]; + color_sum[part] = color_sum[part] + color; + weight_sum[part]++; + } + + for (i = 0; i < partition_count; i++) + { + cluster_centers[i] = color_sum[i] * (1.0f / weight_sum[i]); + } +} + + + + +// after a few rounds of k-means-clustering, we should have a set of 2, 3 or 4 partitions; +// we then turn this set into 2, 3 or 4 bitmaps. Then, for each of the 1024 partitions, +// we try to match the bitmaps as well as possible. + + + + +static inline int bitcount(uint64_t p) +{ + if (sizeof(void *) > 4) + { + uint64_t mask1 = 0x5555555555555555ULL; + uint64_t mask2 = 0x3333333333333333ULL; + uint64_t mask3 = 0x0F0F0F0F0F0F0F0FULL; + // best-known algorithm for 64-bit bitcount, assuming 64-bit processor + // should probably be adapted for use with 32-bit processors and/or processors + // with a POPCNT instruction, but leave that for later. + p -= (p >> 1) & mask1; + p = (p & mask2) + ((p >> 2) & mask2); + p += p >> 4; + p &= mask3; + p *= 0x0101010101010101ULL; + p >>= 56; + return (int)p; + } + else + { + // on 32-bit processor, split the 64-bit input argument in two, + // and bitcount each half separately. + uint32_t p1 = (uint32_t) p; + uint32_t p2 = (uint32_t) (p >> 32); + uint32_t mask1 = 0x55555555U; + uint32_t mask2 = 0x33333333U; + uint32_t mask3 = 0x0F0F0F0FU; + p1 = p1 - ((p1 >> 1) & mask1); + p2 = p2 - ((p2 >> 1) & mask1); + p1 = (p1 & mask2) + ((p1 >> 2) & mask2); + p2 = (p2 & mask2) + ((p2 >> 2) & mask2); + p1 += p1 >> 4; + p2 += p2 >> 4; + p1 &= mask3; + p2 &= mask3; + p1 += p2; + p1 *= 0x01010101U; + p1 >>= 24; + return (int)p1; + } +} + + +// compute the bit-mismatch for a partitioning in 2-partition mode +static inline int partition_mismatch2(uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1) +{ + int v1 = bitcount(a0 ^ b0) + bitcount(a1 ^ b1); + int v2 = bitcount(a0 ^ b1) + bitcount(a1 ^ b0); + return MIN(v1, v2); +} + + +// compute the bit-mismatch for a partitioning in 3-partition mode +static inline int partition_mismatch3(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t b0, uint64_t b1, uint64_t b2) +{ + int p00 = bitcount(a0 ^ b0); + int p01 = bitcount(a0 ^ b1); + int p02 = bitcount(a0 ^ b2); + + int p10 = bitcount(a1 ^ b0); + int p11 = bitcount(a1 ^ b1); + int p12 = bitcount(a1 ^ b2); + + int p20 = bitcount(a2 ^ b0); + int p21 = bitcount(a2 ^ b1); + int p22 = bitcount(a2 ^ b2); + + int s0 = p11 + p22; + int s1 = p12 + p21; + int v0 = MIN(s0, s1) + p00; + + int s2 = p10 + p22; + int s3 = p12 + p20; + int v1 = MIN(s2, s3) + p01; + + int s4 = p10 + p21; + int s5 = p11 + p20; + int v2 = MIN(s4, s5) + p02; + + if (v1 < v0) + v0 = v1; + if (v2 < v0) + v0 = v2; + + // 9 add, 5 MIN + + return v0; +} + +static inline int MIN3(int a, int b, int c) +{ + int d = MIN(a, b); + return MIN(c, d); +} + +// compute the bit-mismatch for a partitioning in 4-partition mode +static inline int partition_mismatch4(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t b0, uint64_t b1, uint64_t b2, uint64_t b3) +{ + int p00 = bitcount(a0 ^ b0); + int p01 = bitcount(a0 ^ b1); + int p02 = bitcount(a0 ^ b2); + int p03 = bitcount(a0 ^ b3); + + int p10 = bitcount(a1 ^ b0); + int p11 = bitcount(a1 ^ b1); + int p12 = bitcount(a1 ^ b2); + int p13 = bitcount(a1 ^ b3); + + int p20 = bitcount(a2 ^ b0); + int p21 = bitcount(a2 ^ b1); + int p22 = bitcount(a2 ^ b2); + int p23 = bitcount(a2 ^ b3); + + int p30 = bitcount(a3 ^ b0); + int p31 = bitcount(a3 ^ b1); + int p32 = bitcount(a3 ^ b2); + int p33 = bitcount(a3 ^ b3); + + int mx23 = MIN(p22 + p33, p23 + p32); + int mx13 = MIN(p21 + p33, p23 + p31); + int mx12 = MIN(p21 + p32, p22 + p31); + int mx03 = MIN(p20 + p33, p23 + p30); + int mx02 = MIN(p20 + p32, p22 + p30); + int mx01 = MIN(p21 + p30, p20 + p31); + + int v0 = p00 + MIN3(p11 + mx23, p12 + mx13, p13 + mx12); + int v1 = p01 + MIN3(p10 + mx23, p12 + mx03, p13 + mx02); + int v2 = p02 + MIN3(p11 + mx03, p10 + mx13, p13 + mx01); + int v3 = p03 + MIN3(p11 + mx02, p12 + mx01, p10 + mx12); + + int x0 = MIN(v0, v1); + int x1 = MIN(v2, v3); + return MIN(x0, x1); + + // 16 bitcount, 17 MIN, 28 ADD +} + + + +void count_partition_mismatch_bits(int xdim, int ydim, int zdim, int partition_count, const uint64_t bitmaps[4], int bitcounts[PARTITION_COUNT]) +{ + int i; + const partition_info *pi = get_partition_table(xdim, ydim, zdim, partition_count); + + if (partition_count == 2) + { + uint64_t bm0 = bitmaps[0]; + uint64_t bm1 = bitmaps[1]; + for (i = 0; i < PARTITION_COUNT; i++) + { + if (pi->partition_count == 2) + { + bitcounts[i] = partition_mismatch2(bm0, bm1, pi->coverage_bitmaps[0], pi->coverage_bitmaps[1]); + } + else + bitcounts[i] = 255; + pi++; + } + } + else if (partition_count == 3) + { + uint64_t bm0 = bitmaps[0]; + uint64_t bm1 = bitmaps[1]; + uint64_t bm2 = bitmaps[2]; + for (i = 0; i < PARTITION_COUNT; i++) + { + if (pi->partition_count == 3) + { + bitcounts[i] = partition_mismatch3(bm0, bm1, bm2, pi->coverage_bitmaps[0], pi->coverage_bitmaps[1], pi->coverage_bitmaps[2]); + } + else + bitcounts[i] = 255; + pi++; + } + } + else if (partition_count == 4) + { + uint64_t bm0 = bitmaps[0]; + uint64_t bm1 = bitmaps[1]; + uint64_t bm2 = bitmaps[2]; + uint64_t bm3 = bitmaps[3]; + for (i = 0; i < PARTITION_COUNT; i++) + { + if (pi->partition_count == 4) + { + bitcounts[i] = partition_mismatch4(bm0, bm1, bm2, bm3, pi->coverage_bitmaps[0], pi->coverage_bitmaps[1], pi->coverage_bitmaps[2], pi->coverage_bitmaps[3]); + } + else + bitcounts[i] = 255; + pi++; + } + } + +} + + +// counting-sort on the mismatch-bits, thereby +// sorting the partitions into an ordering. + +void get_partition_ordering_by_mismatch_bits(const int mismatch_bits[PARTITION_COUNT], int partition_ordering[PARTITION_COUNT]) +{ + int i; + + int mscount[256]; + for (i = 0; i < 256; i++) + mscount[i] = 0; + + for (i = 0; i < PARTITION_COUNT; i++) + mscount[mismatch_bits[i]]++; + + int summa = 0; + for (i = 0; i < 256; i++) + { + int cnt = mscount[i]; + mscount[i] = summa; + summa += cnt; + } + + for (i = 0; i < PARTITION_COUNT; i++) + { + int idx = mscount[mismatch_bits[i]]++; + partition_ordering[idx] = i; + } +} + + + + +void kmeans_compute_partition_ordering(int xdim, int ydim, int zdim, int partition_count, const imageblock * blk, int *ordering) +{ + int i; + + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + + float4 cluster_centers[4]; + int partition_of_texel[MAX_TEXELS_PER_BLOCK]; + + // 3 passes of plain k-means partitioning + for (i = 0; i < 3; i++) + { + if (i == 0) + kpp_initialize(xdim, ydim, zdim, partition_count, blk, cluster_centers); + else + basic_kmeans_update(xdim, ydim, zdim, partition_count, blk, partition_of_texel, cluster_centers); + + basic_kmeans_assign_pass(xdim, ydim, zdim, partition_count, blk, cluster_centers, partition_of_texel); + } + + // at this point, we have a near-ideal partitioning. + + // construct bitmaps + uint64_t bitmaps[4]; + for (i = 0; i < 4; i++) + bitmaps[i] = 0ULL; + + int texels_to_process = bsd->texelcount_for_bitmap_partitioning; + for (i = 0; i < texels_to_process; i++) + { + int idx = bsd->texels_for_bitmap_partitioning[i]; + bitmaps[partition_of_texel[idx]] |= 1ULL << i; + } + + int bitcounts[PARTITION_COUNT]; + // for each entry in the partition table, count bits of partition-mismatch. + count_partition_mismatch_bits(xdim, ydim, zdim, partition_count, bitmaps, bitcounts); + + // finally, sort the partitions by bits-of-partition-mismatch + get_partition_ordering_by_mismatch_bits(bitcounts, ordering); + +} diff --git a/third_party/astcenc/Source/astc_ktx_dds.cpp b/third_party/astcenc/Source/astc_ktx_dds.cpp new file mode 100644 index 0000000000..0714204b5c --- /dev/null +++ b/third_party/astcenc/Source/astc_ktx_dds.cpp @@ -0,0 +1,1577 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2013 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions to load/store KTX and DDS files + * + * The files that are loaded and stored by these functions are + * UNCOMPRESSED files only; the intent is mainly to provide a + * standard way to get HDR and 3D texture data to/from the codec. + * + * Status: only tested on our corpus of images. + */ +/*----------------------------------------------------------------------------*/ +#include "astc_codec_internals.h" + +#include +#include +#include + +#include "softfloat.h" + +enum scanline_copy_method +{ + R8_TO_RGBA8, + RG8_TO_RGBA8, + RGB8_TO_RGBA8, + RGBA8_TO_RGBA8, + BGR8_TO_RGBA8, + BGRA8_TO_RGBA8, + L8_TO_RGBA8, + LA8_TO_RGBA8, + + RGBX8_TO_RGBA8, + BGRX8_TO_RGBA8, + + R16_TO_RGBA16F, + RG16_TO_RGBA16F, + RGB16_TO_RGBA16F, + RGBA16_TO_RGBA16F, + BGR16_TO_RGBA16F, + BGRA16_TO_RGBA16F, + L16_TO_RGBA16F, + LA16_TO_RGBA16F, + + R16F_TO_RGBA16F, + RG16F_TO_RGBA16F, + RGB16F_TO_RGBA16F, + RGBA16F_TO_RGBA16F, + BGR16F_TO_RGBA16F, + BGRA16F_TO_RGBA16F, + L16F_TO_RGBA16F, + LA16F_TO_RGBA16F, + + R32F_TO_RGBA16F, + RG32F_TO_RGBA16F, + RGB32F_TO_RGBA16F, + RGBA32F_TO_RGBA16F, + BGR32F_TO_RGBA16F, + BGRA32F_TO_RGBA16F, + L32F_TO_RGBA16F, + LA32F_TO_RGBA16F +}; + + + +// scanline copying function: this function expands data to RGBA, either U8 or FP16. + +static void copy_scanline(void *dst, const void *src, int pixels, int method) +{ + +#define id(x) (x) +#define u16_sf16(x) float_to_sf16( x * (1.0f/65535.0f), SF_NEARESTEVEN ) +#define f32_sf16(x) sf32_to_sf16( x, SF_NEARESTEVEN ) + +#define COPY_R( dsttype, srctype, convfunc, oneval ) \ + do { \ + srctype *s = (srctype *)src; \ + dsttype *d = (dsttype *)dst; \ + for(i=0;i> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24); +} + + + + + +/* + Notes about KTX: + + After the header and the key/value data area, the actual image data follows. + Each image starts with a 4-byte "imageSize" value indicating the number of bytes of image data follow. + (For cube-maps, this value appears only after first image; the remaining 5 images are all of equal size.) + If the size of an image is not a multiple of 4, then it is padded to the next multiple of 4. + Note that this padding is NOT included in the "imageSize" field. + In a cubemap, the padding appears after each face note that in a 2D/3D texture, padding does + NOT appear between the lines/planes of the texture! + + In a KTX file, there may be multiple images; they are organized as follows: + + For each mipmap_level in numberOfMipmapLevels + UInt32 imageSize; + For each array_element in numberOfArrayElements + * for each face in numberOfFaces + * for each z_slice in pixelDepth + * for each row or row_of_blocks in pixelHeight + * for each pixel or block_of_pixels in pixelWidth + Byte data[format-specific-number-of-bytes] + * end + * end + *end + Byte cubePadding[0-3] + *end + Byte mipPadding[3 - ((imageSize+ 3) % 4)] + *end + + In the ASTC codec, we will, for the time being only harvest the first image, + and we will support only a limited set of formats: + + gl_type: UNSIGNED_BYTE UNSIGNED_SHORT HALF_FLOAT FLOAT UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8_REV + gl_format: RED, RG. RGB, RGBA BGR, BGRA + gl_internal_format: used for upload to OpenGL; we can ignore it on uncompressed-load, but + need to provide a reasonable value on store: RGB8 RGBA8 RGB16F RGBA16F + gl_base_internal_format: same as gl_format unless texture is compressed (well, BGR is turned into RGB) + RED, RG, RGB, RGBA + + */ + + +// enums copied from GL/GL.h +#define GL_RED 0x1903 +#define GL_RG 0x8227 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_HALF_FLOAT 0x140B +#define GL_FLOAT 0x1406 + +struct ktx_header +{ + uint8_t magic[12]; + uint32_t endianness; // should be 0x04030201; if it is instead 0x01020304, then the endianness of everything must be switched. + uint32_t gl_type; // 0 for compressed textures, otherwise value from table 3.2 (page 162) of OpenGL 4.0 spec + uint32_t gl_type_size; // size of data elements to do endianness swap on (1=endian-neutral data) + uint32_t gl_format; // 0 for compressed textures, otherwise value from table 3.3 (page 163) of OpenGLl spec + uint32_t gl_internal_format; // sized-internal-format, corresponding to table 3.12 to 3.14 (pages 182-185) of OpenGL spec + uint32_t gl_base_internal_format; // unsized-internal-format: corresponding to table 3.11 (page 179) of OpenGL spec + uint32_t pixel_width; // texture dimensions; not rounded up to block size for compressed. + uint32_t pixel_height; // must be 0 for 1D textures. + uint32_t pixel_depth; // must be 0 for 1D, 2D and cubemap textures. + uint32_t number_of_array_elements; // 0 if not a texture array + uint32_t number_of_faces; // 6 for cubemaps, 1 for non-cubemaps + uint32_t number_of_mipmap_levels; // 0 or 1 for non-mipmapped textures; 0 indicates that auto-mipmap-gen should be done at load time. + uint32_t bytes_of_key_value_data; // size in bytes of the key-and-value area immediately following the header. +}; + + +// magic 12-byte sequence that must appear at the beginning of every KTX file. +uint8_t ktx_magic[12] = { + 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A +}; + +static void ktx_header_switch_endianness(ktx_header * kt) +{ + #define REV(x) kt->x = u32_byterev( kt->x ) + REV(endianness); + REV(gl_type); + REV(gl_type_size); + REV(gl_format); + REV(gl_internal_format); + REV(gl_base_internal_format); + REV(pixel_width); + REV(pixel_height); + REV(pixel_depth); + REV(number_of_array_elements); + REV(number_of_faces); + REV(number_of_mipmap_levels); + REV(bytes_of_key_value_data); + #undef REV +} + + + + + +astc_codec_image *load_ktx_uncompressed_image(const char *filename, int padding, int *result) +{ + int y, z; + + FILE *f = fopen(filename, "rb"); + if (!f) + { + printf("Failed to open file %s\n", filename); + *result = -1; + return NULL; + } + + ktx_header hdr; + size_t header_bytes_read = fread(&hdr, 1, sizeof(hdr), f); + + if (header_bytes_read != sizeof(hdr)) + { + printf("Failed to read header of KTX file %s\n", filename); + fclose(f); + *result = -2; + return NULL; + } + + if (memcmp(hdr.magic, ktx_magic, 12) != 0 || (hdr.endianness != 0x04030201 && hdr.endianness != 0x01020304)) + { + printf("File %s does not have a valid KTX header\n", filename); + fclose(f); + *result = -3; + return NULL; + } + + int switch_endianness = 0; + if (hdr.endianness == 0x01020304) + { + ktx_header_switch_endianness(&hdr); + switch_endianness = 1; + } + + if (hdr.gl_type == 0 || hdr.gl_format == 0) + { + printf("File %s appears to be compressed, not supported as input\n", filename); + fclose(f); + *result = -4; + return NULL; + } + + // the formats we support are: + + // Cartesian product of gl_type=(UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT) x gl_format=(RED, RG, RGB, RGBA, BGR, BGRA) + + int components; + switch (hdr.gl_format) + { + case GL_RED: + components = 1; + break; + case GL_RG: + components = 2; + break; + case GL_RGB: + components = 3; + break; + case GL_RGBA: + components = 4; + break; + case GL_BGR: + components = 3; + break; + case GL_BGRA: + components = 4; + break; + case GL_LUMINANCE: + components = 1; + break; + case GL_LUMINANCE_ALPHA: + components = 2; + break; + default: + printf("KTX file %s has unsupported GL type\n", filename); + fclose(f); + *result = -5; + return NULL; + }; + + + // Although these are set up later, we include a default initializer to remove warnings + + int bytes_per_component = 1; // bytes per component in the KTX file. + int bitness = 8; // internal precision we will use in the codec. + scanline_copy_method cm = R8_TO_RGBA8; + + switch (hdr.gl_type) + { + case GL_UNSIGNED_BYTE: + { + bitness = 8; + bytes_per_component = 1; + switch (hdr.gl_format) + { + case GL_RED: + cm = R8_TO_RGBA8; + break; + case GL_RG: + cm = RG8_TO_RGBA8; + break; + case GL_RGB: + cm = RGB8_TO_RGBA8; + break; + case GL_RGBA: + cm = RGBA8_TO_RGBA8; + break; + case GL_BGR: + cm = BGR8_TO_RGBA8; + break; + case GL_BGRA: + cm = BGRA8_TO_RGBA8; + break; + case GL_LUMINANCE: + cm = L8_TO_RGBA8; + break; + case GL_LUMINANCE_ALPHA: + cm = LA8_TO_RGBA8; + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + bitness = 16; + bytes_per_component = 2; + switch (hdr.gl_format) + { + case GL_RED: + cm = R16_TO_RGBA16F; + break; + case GL_RG: + cm = RG16_TO_RGBA16F; + break; + case GL_RGB: + cm = RGB16_TO_RGBA16F; + break; + case GL_RGBA: + cm = RGBA16_TO_RGBA16F; + break; + case GL_BGR: + cm = BGR16_TO_RGBA16F; + break; + case GL_BGRA: + cm = BGRA16_TO_RGBA16F; + break; + case GL_LUMINANCE: + cm = L16_TO_RGBA16F; + break; + case GL_LUMINANCE_ALPHA: + cm = LA16_TO_RGBA16F; + break; + } + break; + } + case GL_HALF_FLOAT: + { + bitness = 16; + bytes_per_component = 2; + switch (hdr.gl_format) + { + case GL_RED: + cm = R16F_TO_RGBA16F; + break; + case GL_RG: + cm = RG16F_TO_RGBA16F; + break; + case GL_RGB: + cm = RGB16F_TO_RGBA16F; + break; + case GL_RGBA: + cm = RGBA16F_TO_RGBA16F; + break; + case GL_BGR: + cm = BGR16F_TO_RGBA16F; + break; + case GL_BGRA: + cm = BGRA16F_TO_RGBA16F; + break; + case GL_LUMINANCE: + cm = L16F_TO_RGBA16F; + break; + case GL_LUMINANCE_ALPHA: + cm = LA16F_TO_RGBA16F; + break; + } + break; + } + case GL_FLOAT: + { + bitness = 16; + bytes_per_component = 4; + switch (hdr.gl_format) + { + case GL_RED: + cm = R32F_TO_RGBA16F; + break; + case GL_RG: + cm = RG32F_TO_RGBA16F; + break; + case GL_RGB: + cm = RGB32F_TO_RGBA16F; + break; + case GL_RGBA: + cm = RGBA32F_TO_RGBA16F; + break; + case GL_BGR: + cm = BGR32F_TO_RGBA16F; + break; + case GL_BGRA: + cm = BGRA32F_TO_RGBA16F; + break; + case GL_LUMINANCE: + cm = L32F_TO_RGBA16F; + break; + case GL_LUMINANCE_ALPHA: + cm = LA32F_TO_RGBA16F; + break; + } + break; + } + default: + printf("KTX file %s has unsupported GL format\n", filename); + fclose(f); + *result = -5; + return NULL; + } + + if (hdr.number_of_mipmap_levels > 1) + printf("warning: KTX file %s has %d mipmap levels; only the first one will be encoded.\n", filename, hdr.number_of_mipmap_levels); + + if (hdr.number_of_array_elements > 1) + printf("warning: KTX file %s contains a texture array with %d layers; only the first one will be encoded.\n", filename, hdr.number_of_array_elements); + + if (hdr.number_of_faces > 1) + printf("warning: KTX file %s contains a cubemap with 6 faces; only the first one will be encoded.\n", filename); + + + int xsize = hdr.pixel_width; + int ysize = hdr.pixel_height; + int zsize = hdr.pixel_depth; + + if (ysize == 0) + ysize = 1; + if (zsize == 0) + zsize = 1; + + // ignore the key/value data + fseek(f, hdr.bytes_of_key_value_data, SEEK_CUR); + + uint32_t specified_bytes_of_surface = 0; + size_t sb_read = fread(&specified_bytes_of_surface, 1, 4, f); + if (sb_read != 4) + { + printf("Failed to read header of KTX file %s\n", filename); + fclose(f); + *result = -2; + return NULL; + } + + + if (switch_endianness) + specified_bytes_of_surface = u32_byterev(specified_bytes_of_surface); + + // read the surface + uint32_t xstride = bytes_per_component * components * xsize; + uint32_t ystride = xstride * ysize; + uint32_t computed_bytes_of_surface = zsize * ystride; + if (computed_bytes_of_surface != specified_bytes_of_surface) + { + fclose(f); + printf("%s: KTX file inconsistency: computed surface size is %d bytes, but specified size is %d bytes\n", filename, computed_bytes_of_surface, specified_bytes_of_surface); + *result = -5; + return NULL; + } + + + + uint8_t *buf = (uint8_t *) malloc(specified_bytes_of_surface); + size_t bytes_read = fread(buf, 1, specified_bytes_of_surface, f); + fclose(f); + if (bytes_read != specified_bytes_of_surface) + { + free(buf); + printf("Failed to read file %s\n", filename); + *result = -6; + return NULL; + } + + // perform an endianness swap on the surface if needed. + if (switch_endianness) + { + if (hdr.gl_type_size == 2) + switch_endianness2(buf, specified_bytes_of_surface); + if (hdr.gl_type_size == 4) + switch_endianness4(buf, specified_bytes_of_surface); + } + + + + // then transfer data from the surface to our own image-data-structure. + astc_codec_image *astc_img = allocate_image(bitness, xsize, ysize, zsize, padding); + + for (z = 0; z < zsize; z++) + { + int zdst = (zsize == 1) ? z : z + padding; + for (y = 0; y < ysize; y++) + { + int ydst = y + padding; + void *dst; + if (bitness == 16) + dst = (void *)(astc_img->imagedata16[zdst][ydst] + 4 * padding); + else + dst = (void *)(astc_img->imagedata8[zdst][ydst] + 4 * padding); + + uint8_t *src = buf + (z * ystride) + (y * xstride); + copy_scanline(dst, src, xsize, cm); + } + } + + free(buf); + fill_image_padding_area(astc_img); + *result = components + (bitness == 16 ? 0x80 : 0); + return astc_img; +} + + + + +int store_ktx_uncompressed_image(const astc_codec_image * img, const char *ktx_filename, int bitness) +{ + int x, y, z; + int i, j; + + int xsize = img->xsize; + int ysize = img->ysize; + int zsize = img->zsize; + + int image_channels = determine_image_channels(img); + + ktx_header hdr; + + int gl_format_of_channels[4] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA }; + + memcpy(hdr.magic, ktx_magic, 12); + hdr.endianness = 0x04030201; + hdr.gl_type = (bitness == 16) ? GL_HALF_FLOAT : GL_UNSIGNED_BYTE; + hdr.gl_type_size = bitness / 8; + hdr.gl_format = gl_format_of_channels[image_channels - 1]; + hdr.gl_internal_format = gl_format_of_channels[image_channels - 1]; + hdr.gl_base_internal_format = gl_format_of_channels[image_channels - 1]; + hdr.pixel_width = xsize; + hdr.pixel_height = ysize; + hdr.pixel_depth = (zsize == 1) ? 0 : zsize; + hdr.number_of_array_elements = 0; + hdr.number_of_faces = 1; + hdr.number_of_mipmap_levels = 1; + hdr.bytes_of_key_value_data = 0; + + + // collect image data to write + + uint8_t ***row_pointers8 = NULL; + uint16_t ***row_pointers16 = NULL; + if (bitness == 8) + { + row_pointers8 = new uint8_t **[zsize]; + row_pointers8[0] = new uint8_t *[ysize * zsize]; + row_pointers8[0][0] = new uint8_t[xsize * ysize * zsize * image_channels + 3]; + + for (i = 1; i < zsize; i++) + { + row_pointers8[i] = row_pointers8[0] + ysize * i; + row_pointers8[i][0] = row_pointers8[0][0] + ysize * xsize * image_channels * i; + } + for (i = 0; i < zsize; i++) + for (j = 1; j < ysize; j++) + row_pointers8[i][j] = row_pointers8[i][0] + xsize * image_channels * j; + + for (z = 0; z < zsize; z++) + { + for (y = 0; y < ysize; y++) + { + switch (image_channels) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][x] = img->imagedata8[z][y][4 * x]; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][2 * x] = img->imagedata8[z][y][4 * x]; + row_pointers8[z][y][2 * x + 1] = img->imagedata8[z][y][4 * x + 3]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][3 * x] = img->imagedata8[z][y][4 * x]; + row_pointers8[z][y][3 * x + 1] = img->imagedata8[z][y][4 * x + 1]; + row_pointers8[z][y][3 * x + 2] = img->imagedata8[z][y][4 * x + 2]; + } + break; + case 4: // four-component, treated as RGBA + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][4 * x] = img->imagedata8[z][y][4 * x]; + row_pointers8[z][y][4 * x + 1] = img->imagedata8[z][y][4 * x + 1]; + row_pointers8[z][y][4 * x + 2] = img->imagedata8[z][y][4 * x + 2]; + row_pointers8[z][y][4 * x + 3] = img->imagedata8[z][y][4 * x + 3]; + } + break; + } + } + } + } + else // if bitness == 16 + { + row_pointers16 = new uint16_t **[zsize]; + row_pointers16[0] = new uint16_t *[ysize * zsize]; + row_pointers16[0][0] = new uint16_t[xsize * ysize * zsize * image_channels + 1]; + + for (i = 1; i < zsize; i++) + { + row_pointers16[i] = row_pointers16[0] + ysize * i; + row_pointers16[i][0] = row_pointers16[0][0] + ysize * xsize * image_channels * i; + } + for (i = 0; i < zsize; i++) + for (j = 1; j < ysize; j++) + row_pointers16[i][j] = row_pointers16[i][0] + xsize * image_channels * j; + + for (z = 0; z < zsize; z++) + { + for (y = 0; y < ysize; y++) + { + switch (image_channels) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][x] = img->imagedata16[z][y][4 * x]; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][2 * x] = img->imagedata16[z][y][4 * x]; + row_pointers16[z][y][2 * x + 1] = img->imagedata16[z][y][4 * x + 3]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][3 * x] = img->imagedata16[z][y][4 * x]; + row_pointers16[z][y][3 * x + 1] = img->imagedata16[z][y][4 * x + 1]; + row_pointers16[z][y][3 * x + 2] = img->imagedata16[z][y][4 * x + 2]; + } + break; + case 4: // four-component, treated as RGBA + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][4 * x] = img->imagedata16[z][y][4 * x]; + row_pointers16[z][y][4 * x + 1] = img->imagedata16[z][y][4 * x + 1]; + row_pointers16[z][y][4 * x + 2] = img->imagedata16[z][y][4 * x + 2]; + row_pointers16[z][y][4 * x + 3] = img->imagedata16[z][y][4 * x + 3]; + } + break; + } + } + } + } + + int retval = image_channels + (bitness == 16 ? 0x80 : 0); + uint32_t image_bytes = xsize * ysize * zsize * image_channels * (bitness / 8); + uint32_t image_write_bytes = (image_bytes + 3) & ~3; + + FILE *wf = fopen(ktx_filename, "wb"); + if (wf) + { + void *dataptr = (bitness == 16) ? (void *)(row_pointers16[0][0]) : (void *)(row_pointers8[0][0]); + + size_t expected_bytes_written = sizeof(ktx_header) + image_write_bytes + 4; + size_t hdr_bytes_written = fwrite(&hdr, 1, sizeof(ktx_header), wf); + size_t bytecount_bytes_written = fwrite(&image_bytes, 1, 4, wf); + size_t data_bytes_written = fwrite(dataptr, 1, image_write_bytes, wf); + fclose(wf); + if (hdr_bytes_written + bytecount_bytes_written + data_bytes_written != expected_bytes_written) + retval = -1; + + } + else + { + retval = -1; + } + + if (row_pointers8) + { + delete[]row_pointers8[0][0]; + delete[]row_pointers8[0]; + delete[]row_pointers8; + } + if (row_pointers16) + { + delete[]row_pointers16[0][0]; + delete[]row_pointers16[0]; + delete[]row_pointers16; + } + + return retval; +} + + + + +/* + Loader for DDS files. + + Note that after the header, data are densely packed with no padding; + in the case of multiple surfaces, they appear one after another in + the file, again with no padding. + + This code is NOT endian-neutral. +*/ + +struct dds_pixelformat +{ + uint32_t size; // structure size, set to 32. + /* + flags bits are a combination of the following: 0x1 : Texture contains alpha data 0x2 : ---- (older files: texture contains alpha data, for Alpha-only texture) 0x4 : The fourcc field is valid, + indicating a compressed or DX10 texture format 0x40 : texture contains uncompressed RGB data 0x200 : ---- (YUV in older files) 0x20000 : Texture contains Luminance data (can be combined with + 0x1 for Lum-Alpha) */ + uint32_t flags; + uint32_t fourcc; // "DX10" to indicate a DX10 format, "DXTn" for the DXT formats + uint32_t rgbbitcount; // number of bits per texel; up to 32 for non-DX10 formats. + uint32_t rbitmask; // bitmap indicating position of red/luminance color component + uint32_t gbitmask; // bitmap indicating position of green color component + uint32_t bbitmask; // bitmap indicating position of blue color component + uint32_t abitmask; // bitmap indicating position of alpha color component +}; + + +struct dds_header +{ + uint32_t size; // header size; must be exactly 124. + /* + flag field is an OR or the following bits, that indicate fields containing valid data: + 1: caps/caps2/caps3/caps4 (set in all DDS files, ignore on read) + 2: height (set in all DDS files, ignore on read) + 4: width (set in all DDS files, ignore on read) + 8: pitch (for uncompressed texture) + 0x1000: the pixel format field (set in all DDS files, ignore on read) + 0x20000: mipmap count (for mipmapped textures with >1 level) + 0x80000: pitch (for compressed texture) + 0x800000: depth (for 3d textures) + */ + uint32_t flags; + uint32_t height; + uint32_t width; + uint32_t pitch_or_linear_size; // scanline pitch for uncompressed; total size in bytes for compressed + uint32_t depth; + uint32_t mipmapcount; + // unused, set to 0 + uint32_t reserved1[11]; + dds_pixelformat ddspf; + /* + caps field is an OR of the following values: + 8 : should be set for a file that contains more than 1 surface (ignore on read) + 0x400000 : should be set for a mipmapped texture + 0x1000 : should be set if the surface is a texture at all (all DDS files, ignore on read) + */ + uint32_t caps; + /* + caps2 field is an OR of the following values: + 0x200 : texture is cubemap + 0x400 : +X face of cubemap is present + 0x800 : -X face of cubemap is present + 0x1000 : +Y face of cubemap is present + 0x2000 : -Y face of cubemap is present + 0x4000 : +Z face of cubemap is present + 0x8000 : -Z face of cubemap is present + 0x200000 : texture is a 3d texture. + */ + uint32_t caps2; + // unused, set to 0 + uint32_t caps3; + // unused, set to 0 + uint32_t caps4; + // unused, set to 0 + uint32_t reserved2; +}; + + +struct dds_header_dx10 +{ + uint32_t dxgi_format; + uint32_t resource_dimension; // 2=1d-texture, 3=2d-texture or cubemap, 4=3d-texture + uint32_t misc_flag; // 4 if cubemap, else 0 + uint32_t array_size; // size of array in case of a texture array; set to 1 for a non-array + uint32_t reserved; // set to 0. +}; + + +#define DDS_MAGIC 0x20534444 +#define DX10_MAGIC 0x30315844 + + +astc_codec_image *load_dds_uncompressed_image(const char *filename, int padding, int *result) +{ + int i; + int y, z; + + FILE *f = fopen(filename, "rb"); + if (!f) + { + printf("Failed to open file %s\n", filename); + *result = -1; + return NULL; + } + + uint8_t magic[4]; + + dds_header hdr; + size_t magic_bytes_read = fread(magic, 1, 4, f); + size_t header_bytes_read = fread(&hdr, 1, sizeof(hdr), f); + if (magic_bytes_read != 4 || header_bytes_read != sizeof(hdr)) + { + printf("Failed to read header of DDS file %s\n", filename); + fclose(f); + *result = -2; + return NULL; + } + + uint32_t magicx = magic[0] | (magic[1] << 8) | (magic[2] << 16) | (magic[3] << 24); + + if (magicx != DDS_MAGIC || hdr.size != 124) + { + printf("File %s does not have a valid DDS header\n", filename); + fclose(f); + *result = -3; + return NULL; + } + + int use_dx10_header = 0; + if (hdr.ddspf.flags & 4) + { + if (hdr.ddspf.fourcc == DX10_MAGIC) + { + use_dx10_header = 1; + } + else + { + printf("DDS file %s is compressed, not supported\n", filename); + fclose(f); + *result = -4; + return NULL; + } + } + + dds_header_dx10 dx10_header; + if (use_dx10_header) + { + size_t dx10_header_bytes_read = fread(&dx10_header, 1, sizeof(dx10_header), f); + if (dx10_header_bytes_read != sizeof(dx10_header)) + { + printf("Failed to read header of DDS file %s\n", filename); + fclose(f); + *result = -2; + return NULL; + } + } + + + int xsize = hdr.width; + int ysize = hdr.height; + int zsize = (hdr.flags & 0x800000) ? hdr.depth : 1; + + + int bitness; // the bitcount that we will use internally in the codec + int bytes_per_component; // the bytes per component in the DDS file itself + int components; + int copy_method; + + // figure out the format actually used in the DDS file. + if (use_dx10_header) + { + + // DX10 header present; use the DXGI format. + + #define DXGI_FORMAT_R32G32B32A32_FLOAT 2 + #define DXGI_FORMAT_R32G32B32_FLOAT 6 + #define DXGI_FORMAT_R16G16B16A16_FLOAT 10 + #define DXGI_FORMAT_R16G16B16A16_UNORM 11 + #define DXGI_FORMAT_R32G32_FLOAT 16 + #define DXGI_FORMAT_R8G8B8A8_UNORM 28 + #define DXGI_FORMAT_R16G16_FLOAT 34 + #define DXGI_FORMAT_R16G16_UNORM 35 + #define DXGI_FORMAT_R32_FLOAT 41 + #define DXGI_FORMAT_R8G8_UNORM 49 + #define DXGI_FORMAT_R16_FLOAT 54 + #define DXGI_FORMAT_R16_UNORM 56 + #define DXGI_FORMAT_R8_UNORM 61 + #define DXGI_FORMAT_B8G8R8A8_UNORM 86 + #define DXGI_FORMAT_B8G8R8X8_UNORM 87 + + struct dxgi_params + { + int bitness; + int bytes_per_component; + int components; + int copy_method; + uint32_t dxgi_format_number; + }; + + static const dxgi_params format_params[] = { + {16, 4, 4, RGBA32F_TO_RGBA16F, DXGI_FORMAT_R32G32B32A32_FLOAT}, + {16, 4, 3, RGB32F_TO_RGBA16F, DXGI_FORMAT_R32G32B32_FLOAT}, + {16, 2, 4, RGBA16F_TO_RGBA16F, DXGI_FORMAT_R16G16B16A16_FLOAT}, + {16, 2, 4, RGBA16_TO_RGBA16F, DXGI_FORMAT_R16G16B16A16_UNORM}, + {16, 4, 2, RG32F_TO_RGBA16F, DXGI_FORMAT_R32G32_FLOAT}, + {8, 1, 4, RGBA8_TO_RGBA8, DXGI_FORMAT_R8G8B8A8_UNORM}, + {16, 2, 2, RG16F_TO_RGBA16F, DXGI_FORMAT_R16G16_FLOAT}, + {16, 2, 2, RG16_TO_RGBA16F, DXGI_FORMAT_R16G16_UNORM}, + {16, 4, 1, R32F_TO_RGBA16F, DXGI_FORMAT_R32_FLOAT}, + {8, 1, 2, RG8_TO_RGBA8, DXGI_FORMAT_R8G8_UNORM}, + {16, 2, 1, R16F_TO_RGBA16F, DXGI_FORMAT_R16_FLOAT}, + {16, 2, 1, R16_TO_RGBA16F, DXGI_FORMAT_R16_UNORM}, + {8, 1, 1, R8_TO_RGBA8, DXGI_FORMAT_R8_UNORM}, + {8, 1, 4, BGRA8_TO_RGBA8, DXGI_FORMAT_B8G8R8A8_UNORM}, + {8, 1, 4, BGRX8_TO_RGBA8, DXGI_FORMAT_B8G8R8X8_UNORM}, + }; + + + int dxgi_modes_supported = sizeof(format_params) / sizeof(format_params[0]); + int did_select_format = 0; + for (i = 0; i < dxgi_modes_supported; i++) + { + if (dx10_header.dxgi_format == format_params[i].dxgi_format_number) + { + bitness = format_params[i].bitness; + bytes_per_component = format_params[i].bytes_per_component; + components = format_params[i].components; + copy_method = format_params[i].copy_method; + did_select_format = 1; + break; + } + } + + if (did_select_format == 0) + { + printf("DDS file %s: DXGI format not supported by codec\n", filename); + fclose(f); + *result = -4; + return NULL; + } + } + + else + { + // No DX10 header present. Then try to match the bitcount and bitmask against + // a set of prepared patterns. + uint32_t flags = hdr.ddspf.flags; + uint32_t bitcount = hdr.ddspf.rgbbitcount; + uint32_t rmask = hdr.ddspf.rbitmask; + uint32_t gmask = hdr.ddspf.gbitmask; + uint32_t bmask = hdr.ddspf.bbitmask; + uint32_t amask = hdr.ddspf.abitmask; + + + // RGBA-unorm8 + if ((flags & 0x41) == 0x41 && bitcount == 32 && rmask == 0xFF && gmask == 0xFF00 && bmask == 0xFF0000 && amask == 0xFF000000) + { + bytes_per_component = 1; + components = 4; + copy_method = RGBA8_TO_RGBA8; + } + // BGRA-unorm8 + else if ((flags & 0x41) == 0x41 && bitcount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF && amask == 0xFF000000) + { + bytes_per_component = 1; + components = 4; + copy_method = BGRA8_TO_RGBA8; + } + // RGBX-unorm8 + else if ((flags & 0x40) && bitcount == 32 && rmask == 0xFF && gmask == 0xFF00 && bmask == 0xFF0000) + { + bytes_per_component = 1; + components = 4; + copy_method = RGBX8_TO_RGBA8; + } + // BGRX-unorm8 + else if ((flags & 0x40) && bitcount == 32 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF) + { + bytes_per_component = 1; + components = 4; + copy_method = BGRX8_TO_RGBA8; + } + // RGB-unorm8 + else if ((flags & 0x40) && bitcount == 24 && rmask == 0xFF && gmask == 0xFF00 && bmask == 0xFF0000) + { + bytes_per_component = 1; + components = 3; + copy_method = RGB8_TO_RGBA8; + } + // BGR-unorm8 + else if ((flags & 0x40) && bitcount == 24 && rmask == 0xFF0000 && gmask == 0xFF00 && bmask == 0xFF) + { + bytes_per_component = 1; + components = 3; + copy_method = BGR8_TO_RGBA8; + } + // RG-unorm16 + else if ((flags & 0x40) && bitcount == 16 && rmask == 0xFFFF && gmask == 0xFFFF0000) + { + bytes_per_component = 2; + components = 2; + copy_method = RG16_TO_RGBA16F; + } + // A8L8 + else if ((flags & 0x20001) == 0x20001 && bitcount == 16 && rmask == 0xFF && amask == 0xFF00) + { + bytes_per_component = 1; + components = 2; + copy_method = LA8_TO_RGBA8; + } + // L8 + else if ((flags & 0x20000) && bitcount == 8 && rmask == 0xFF) + { + bytes_per_component = 1; + components = 1; + copy_method = L8_TO_RGBA8; + } + // L16 + else if ((flags & 0x20000) && bitcount == 16 && rmask == 0xFFFF) + { + bytes_per_component = 2; + components = 1; + copy_method = L16_TO_RGBA16F; + } + else + { + printf("DDS file %s: Non-DXGI format not supported by codec\n", filename); + fclose(f); + *result = -4; + return NULL; + } + + bitness = bytes_per_component * 8; + } + + + // then, load the actual file. + uint32_t xstride = bytes_per_component * components * xsize; + uint32_t ystride = xstride * ysize; + uint32_t bytes_of_surface = zsize * ystride; + + uint8_t *buf = (uint8_t *) malloc(bytes_of_surface); + size_t bytes_read = fread(buf, 1, bytes_of_surface, f); + fclose(f); + if (bytes_read != bytes_of_surface) + { + free(buf); + printf("Failed to read file %s\n", filename); + *result = -6; + return NULL; + } + + // then transfer data from the surface to our own image-data-structure. + astc_codec_image *astc_img = allocate_image(bitness, xsize, ysize, zsize, padding); + + for (z = 0; z < zsize; z++) + { + int zdst = zsize == 1 ? z : z + padding; + for (y = 0; y < ysize; y++) + { + int ydst = y + padding; + void *dst; + if (bitness == 16) + dst = (void *)(astc_img->imagedata16[zdst][ydst] + 4 * padding); + else + dst = (void *)(astc_img->imagedata8[zdst][ydst] + 4 * padding); + + uint8_t *src = buf + (z * ystride) + (y * xstride); + copy_scanline(dst, src, xsize, copy_method); + } + } + + free(buf); + fill_image_padding_area(astc_img); + *result = components + (bitness == 16 ? 0x80 : 0); + return astc_img; +} + + + +int store_dds_uncompressed_image(const astc_codec_image * img, const char *dds_filename, int bitness) +{ + int i, j; + int x, y, z; + + int xsize = img->xsize; + int ysize = img->ysize; + int zsize = img->zsize; + + int image_channels = (bitness == 16) ? 4 : determine_image_channels(img); + + + // DDS-pixel-format structures to use when storing LDR image with 1,2,3 or 4 components. + static const dds_pixelformat format_of_image_channels[4] = + { + {32, 0x20000, 0, 8, 0xFF, 0, 0, 0}, // luminance + {32, 0x20001, 0, 16, 0xFF, 0, 0, 0xFF00}, // L8A8 + {32, 0x40, 0, 24, 0xFF, 0xFF00, 0xFF0000, 0}, // RGB8 + {32, 0x41, 0, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000} // RGBA8 + }; + + // DDS-pixel-format structures to use when storing HDR image. + static const dds_pixelformat dxt10_diverter = + { + 32, 4, DX10_MAGIC, 0, 0, 0, 0, 0 + }; + + + // header handling. We will write: + // * DDS magic value + // * DDS header + // * DDS DX10 header, if the file is floating-point + // * pixel data. + + // main header data + dds_header hdr; + hdr.size = 124; + hdr.flags = 0x100F | (zsize > 1 ? 0x800000 : 0); + hdr.height = ysize; + hdr.width = xsize; + hdr.pitch_or_linear_size = image_channels * (bitness / 8) * xsize; + hdr.depth = zsize; + hdr.mipmapcount = 1; + for (i = 0; i < 11; i++) + hdr.reserved1[i] = 0; + hdr.caps = 0x1000; + hdr.caps2 = (zsize > 1) ? 0x200000 : 0; + hdr.caps3 = 0; + hdr.caps4 = 0; + + // pixel-format data + if (bitness == 8) + hdr.ddspf = format_of_image_channels[image_channels - 1]; + else + hdr.ddspf = dxt10_diverter; + + // DX10 data + dds_header_dx10 dx10; + dx10.dxgi_format = DXGI_FORMAT_R16G16B16A16_FLOAT; + dx10.resource_dimension = (zsize > 1) ? 4 : 3; + dx10.misc_flag = 0; + dx10.array_size = 1; + dx10.reserved = 0; + + + // collect image data to write + + uint8_t ***row_pointers8 = NULL; + uint16_t ***row_pointers16 = NULL; + if (bitness == 8) + { + row_pointers8 = new uint8_t **[zsize]; + row_pointers8[0] = new uint8_t *[ysize * zsize]; + row_pointers8[0][0] = new uint8_t[xsize * ysize * zsize * image_channels]; + + for (i = 1; i < zsize; i++) + { + row_pointers8[i] = row_pointers8[0] + ysize * i; + row_pointers8[i][0] = row_pointers8[0][0] + ysize * xsize * image_channels * i; + } + for (i = 0; i < zsize; i++) + for (j = 1; j < ysize; j++) + row_pointers8[i][j] = row_pointers8[i][0] + xsize * image_channels * j; + + for (z = 0; z < zsize; z++) + { + for (y = 0; y < ysize; y++) + { + switch (image_channels) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][x] = img->imagedata8[z][y][4 * x]; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][2 * x] = img->imagedata8[z][y][4 * x]; + row_pointers8[z][y][2 * x + 1] = img->imagedata8[z][y][4 * x + 3]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][3 * x] = img->imagedata8[z][y][4 * x]; + row_pointers8[z][y][3 * x + 1] = img->imagedata8[z][y][4 * x + 1]; + row_pointers8[z][y][3 * x + 2] = img->imagedata8[z][y][4 * x + 2]; + } + break; + case 4: // four-component, treated as RGBA + for (x = 0; x < xsize; x++) + { + row_pointers8[z][y][4 * x] = img->imagedata8[z][y][4 * x]; + row_pointers8[z][y][4 * x + 1] = img->imagedata8[z][y][4 * x + 1]; + row_pointers8[z][y][4 * x + 2] = img->imagedata8[z][y][4 * x + 2]; + row_pointers8[z][y][4 * x + 3] = img->imagedata8[z][y][4 * x + 3]; + } + break; + } + } + } + } + else // if bitness == 16 + { + row_pointers16 = new uint16_t **[zsize]; + row_pointers16[0] = new uint16_t *[ysize * zsize]; + row_pointers16[0][0] = new uint16_t[xsize * ysize * zsize * image_channels]; + + for (i = 1; i < zsize; i++) + { + row_pointers16[i] = row_pointers16[0] + ysize * i; + row_pointers16[i][0] = row_pointers16[0][0] + ysize * xsize * image_channels * i; + } + for (i = 0; i < zsize; i++) + for (j = 1; j < ysize; j++) + row_pointers16[i][j] = row_pointers16[i][0] + xsize * image_channels * j; + + for (z = 0; z < zsize; z++) + { + for (y = 0; y < ysize; y++) + { + switch (image_channels) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][x] = img->imagedata16[z][y][4 * x]; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][2 * x] = img->imagedata16[z][y][4 * x]; + row_pointers16[z][y][2 * x + 1] = img->imagedata16[z][y][4 * x + 3]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][3 * x] = img->imagedata16[z][y][4 * x]; + row_pointers16[z][y][3 * x + 1] = img->imagedata16[z][y][4 * x + 1]; + row_pointers16[z][y][3 * x + 2] = img->imagedata16[z][y][4 * x + 2]; + } + break; + case 4: // four-component, treated as RGBA + for (x = 0; x < xsize; x++) + { + row_pointers16[z][y][4 * x] = img->imagedata16[z][y][4 * x]; + row_pointers16[z][y][4 * x + 1] = img->imagedata16[z][y][4 * x + 1]; + row_pointers16[z][y][4 * x + 2] = img->imagedata16[z][y][4 * x + 2]; + row_pointers16[z][y][4 * x + 3] = img->imagedata16[z][y][4 * x + 3]; + } + break; + } + } + } + } + + int retval = image_channels; + uint32_t image_bytes = xsize * ysize * zsize * image_channels * (bitness / 8); + + uint32_t dds_magic = DDS_MAGIC; + + FILE *wf = fopen(dds_filename, "wb"); + if (wf) + { + void *dataptr = (bitness == 16) ? (void *)(row_pointers16[0][0]) : (void *)(row_pointers8[0][0]); + + size_t expected_bytes_written = 4 + sizeof(dds_header) + (bitness > 8 ? sizeof(dds_header_dx10) : 0) + image_bytes; + + size_t magic_bytes_written = fwrite(&dds_magic, 1, 4, wf); + size_t hdr_bytes_written = fwrite(&hdr, 1, sizeof(dds_header), wf); + + size_t dx10_bytes_written; + if (bitness > 8) + dx10_bytes_written = fwrite(&dx10, 1, sizeof(dx10), wf); + else + dx10_bytes_written = 0; + + size_t data_bytes_written = fwrite(dataptr, 1, image_bytes, wf); + + fclose(wf); + if (magic_bytes_written + hdr_bytes_written + dx10_bytes_written + data_bytes_written != expected_bytes_written) + retval = -1; + } + else + { + retval = -1; + } + + if (row_pointers8) + { + delete[]row_pointers8[0][0]; + delete[]row_pointers8[0]; + delete[]row_pointers8; + } + if (row_pointers16) + { + delete[]row_pointers16[0][0]; + delete[]row_pointers16[0]; + delete[]row_pointers16; + } + + return retval; +} diff --git a/third_party/astcenc/Source/astc_partition_tables.cpp b/third_party/astcenc/Source/astc_partition_tables.cpp new file mode 100644 index 0000000000..7e0a46011c --- /dev/null +++ b/third_party/astcenc/Source/astc_partition_tables.cpp @@ -0,0 +1,323 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions to generate partition tables for ASTC. + * + * We generate tables only for the block sizes that have actually been + * specified to the codec. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +static partition_info **partition_tables[4096]; + +/* + Produce a canonicalized representation of a partition pattern + + The largest possible such representation is 432 bits, equal to 7 uint64_t values. +*/ +static void gen_canonicalized_partition_table(int texel_count, const uint8_t * partition_table, uint64_t canonicalized[7]) +{ + int i; + for (i = 0; i < 7; i++) + canonicalized[i] = 0; + + int mapped_index[4]; + int map_weight_count = 0; + for (i = 0; i < 4; i++) + mapped_index[i] = -1; + + for (i = 0; i < texel_count; i++) + { + int index = partition_table[i]; + if (mapped_index[index] == -1) + mapped_index[index] = map_weight_count++; + uint64_t xlat_index = mapped_index[index]; + canonicalized[i >> 5] |= xlat_index << (2 * (i & 0x1F)); + } +} + + +static int compare_canonicalized_partition_tables(const uint64_t part1[7], const uint64_t part2[7]) +{ + if (part1[0] != part2[0]) + return 0; + if (part1[1] != part2[1]) + return 0; + if (part1[2] != part2[2]) + return 0; + if (part1[3] != part2[3]) + return 0; + if (part1[4] != part2[4]) + return 0; + if (part1[5] != part2[5]) + return 0; + if (part1[6] != part2[6]) + return 0; + return 1; +} + + +/* + For a partition table, detect partitionings that are equivalent, then mark them as invalid. This reduces the number of partitions that the codec has to consider and thus improves encode + performance. */ +static void partition_table_zap_equal_elements(int xdim, int ydim, int zdim, partition_info * pi) +{ + int partition_tables_zapped = 0; + + int texel_count = xdim * ydim * zdim; + + int i, j; + uint64_t *canonicalizeds = new uint64_t[PARTITION_COUNT * 7]; + + + for (i = 0; i < PARTITION_COUNT; i++) + { + gen_canonicalized_partition_table(texel_count, pi[i].partition_of_texel, canonicalizeds + i * 7); + } + + for (i = 0; i < PARTITION_COUNT; i++) + { + for (j = 0; j < i; j++) + { + if (compare_canonicalized_partition_tables(canonicalizeds + 7 * i, canonicalizeds + 7 * j)) + { + pi[i].partition_count = 0; + partition_tables_zapped++; + break; + } + } + } + delete[]canonicalizeds; +} + + +uint32_t hash52(uint32_t inp) +{ + inp ^= inp >> 15; + + inp *= 0xEEDE0891; // (2^4+1)*(2^7+1)*(2^17-1) + inp ^= inp >> 5; + inp += inp << 16; + inp ^= inp >> 7; + inp ^= inp >> 3; + inp ^= inp << 6; + inp ^= inp >> 17; + return inp; +} + + + +int select_partition(int seed, int x, int y, int z, int partitioncount, int small_block) +{ + if (small_block) + { + x <<= 1; + y <<= 1; + z <<= 1; + } + + seed += (partitioncount - 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, sh3; + if (seed & 1) + { + sh1 = (seed & 2 ? 4 : 5); + sh2 = (partitioncount == 3 ? 6 : 5); + } + else + { + sh1 = (partitioncount == 3 ? 6 : 5); + sh2 = (seed & 2 ? 4 : 5); + } + 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 (partitioncount <= 3) + d = 0; + if (partitioncount <= 2) + c = 0; + if (partitioncount <= 1) + b = 0; + + int 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; +} + + + +void generate_one_partition_table(int xdim, int ydim, int zdim, int partition_count, int partition_index, partition_info * pt) +{ + int small_block = (xdim * ydim * zdim) < 32; + + uint8_t *partition_of_texel = pt->partition_of_texel; + int x, y, z, i; + + + for (z = 0; z < zdim; z++) + for (y = 0; y < ydim; y++) + for (x = 0; x < xdim; x++) + { + uint8_t part = select_partition(partition_index, x, y, z, partition_count, small_block); + *partition_of_texel++ = part; + } + + + int texels_per_block = xdim * ydim * zdim; + + int counts[4]; + for (i = 0; i < 4; i++) + counts[i] = 0; + + for (i = 0; i < texels_per_block; i++) + { + int partition = pt->partition_of_texel[i]; + pt->texels_of_partition[partition][counts[partition]++] = i; + } + + for (i = 0; i < 4; i++) + pt->texels_per_partition[i] = counts[i]; + + if (counts[0] == 0) + pt->partition_count = 0; + else if (counts[1] == 0) + pt->partition_count = 1; + else if (counts[2] == 0) + pt->partition_count = 2; + else if (counts[3] == 0) + pt->partition_count = 3; + else + pt->partition_count = 4; + + + + for (i = 0; i < 4; i++) + pt->coverage_bitmaps[i] = 0ULL; + + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + int texels_to_process = bsd->texelcount_for_bitmap_partitioning; + for (i = 0; i < texels_to_process; i++) + { + int idx = bsd->texels_for_bitmap_partitioning[i]; + pt->coverage_bitmaps[pt->partition_of_texel[idx]] |= 1ULL << i; + } + +} + +static void generate_partition_tables(int xdim, int ydim, int zdim) +{ + int i; + + + partition_info *one_partition = new partition_info; + partition_info *two_partitions = new partition_info[1024]; + partition_info *three_partitions = new partition_info[1024]; + partition_info *four_partitions = new partition_info[1024]; + + partition_info **partition_table = new partition_info *[5]; + partition_table[0] = NULL; + partition_table[1] = one_partition; + partition_table[2] = two_partitions; + partition_table[3] = three_partitions; + partition_table[4] = four_partitions; + + generate_one_partition_table(xdim, ydim, zdim, 1, 0, one_partition); + for (i = 0; i < 1024; i++) + { + generate_one_partition_table(xdim, ydim, zdim, 2, i, two_partitions + i); + generate_one_partition_table(xdim, ydim, zdim, 3, i, three_partitions + i); + generate_one_partition_table(xdim, ydim, zdim, 4, i, four_partitions + i); + } + + partition_table_zap_equal_elements(xdim, ydim, zdim, two_partitions); + partition_table_zap_equal_elements(xdim, ydim, zdim, three_partitions); + partition_table_zap_equal_elements(xdim, ydim, zdim, four_partitions); + + partition_tables[xdim + 16 * ydim + 256 * zdim] = partition_table; +} + + +const partition_info *get_partition_table(int xdim, int ydim, int zdim, int partition_count) +{ + int ptindex = xdim + 16 * ydim + 256 * zdim; + if (partition_tables[ptindex] == NULL) + generate_partition_tables(xdim, ydim, zdim); + + return partition_tables[ptindex][partition_count]; +} diff --git a/third_party/astcenc/Source/astc_percentile_tables.cpp b/third_party/astcenc/Source/astc_percentile_tables.cpp new file mode 100644 index 0000000000..6b96ef8cf7 --- /dev/null +++ b/third_party/astcenc/Source/astc_percentile_tables.cpp @@ -0,0 +1,4768 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Percentile tables for ASTC. + */ +/*----------------------------------------------------------------------------*/ + +extern const float percentile_table_4x4[2048]; +extern const float percentile_table_4x5[2048]; +extern const float percentile_table_4x6[2048]; +extern const float percentile_table_4x8[2048]; +extern const float percentile_table_4x10[2048]; +extern const float percentile_table_4x12[2048]; +extern const float percentile_table_5x4[2048]; +extern const float percentile_table_5x5[2048]; +extern const float percentile_table_5x6[2048]; +extern const float percentile_table_5x8[2048]; +extern const float percentile_table_5x10[2048]; +extern const float percentile_table_5x12[2048]; +extern const float percentile_table_6x4[2048]; +extern const float percentile_table_6x5[2048]; +extern const float percentile_table_6x6[2048]; +extern const float percentile_table_6x8[2048]; +extern const float percentile_table_6x10[2048]; +extern const float percentile_table_6x12[2048]; +extern const float percentile_table_8x4[2048]; +extern const float percentile_table_8x5[2048]; +extern const float percentile_table_8x6[2048]; +extern const float percentile_table_8x8[2048]; +extern const float percentile_table_8x10[2048]; +extern const float percentile_table_8x12[2048]; +extern const float percentile_table_10x4[2048]; +extern const float percentile_table_10x5[2048]; +extern const float percentile_table_10x6[2048]; +extern const float percentile_table_10x8[2048]; +extern const float percentile_table_10x10[2048]; +extern const float percentile_table_10x12[2048]; +extern const float percentile_table_12x4[2048]; +extern const float percentile_table_12x5[2048]; +extern const float percentile_table_12x6[2048]; +extern const float percentile_table_12x8[2048]; +extern const float percentile_table_12x10[2048]; +extern const float percentile_table_12x12[2048]; + + +const float percentile_table_4x4[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.8661f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7732f, 0.8567f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7818f, 0.8914f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.4578f, 0.5679f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4183f, 0.4961f, 0.5321f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9151f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9400f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9678f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8111f, 0.8833f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8299f, 0.8988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9182f, 0.9692f, 0.9820f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9663f, 0.9911f, 0.8707f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9088f, 0.9374f, 0.8793f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8750f, 0.8952f, 0.7356f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2746f, 0.0000f, 0.0772f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.1487f, 0.2193f, 0.3263f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9917f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9996f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9516f, 0.9838f, 0.9927f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9731f, 0.9906f, 0.9448f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9900f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9991f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.9987f, 0.9936f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9985f, 0.9615f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9269f, 0.9577f, 0.9057f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9023f, 0.9241f, 0.7499f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9757f, 0.9846f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9922f, 0.9932f, 0.9792f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9881f, 0.9494f, 0.8178f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9780f, 0.8518f, 0.6206f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9472f, 0.7191f, 0.7003f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8356f, 0.3772f, 0.9971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9769f, 0.9875f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, 0.9941f, 0.9861f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9956f, 0.9982f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9868f, 0.9854f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9888f, 0.9811f, 0.9706f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9894f, 0.9425f, 0.8465f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9718f, 0.8614f, 0.6422f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9648f, 0.9212f, 0.8412f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9596f, 0.9557f, 0.9537f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9999f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, 0.9984f, 0.9958f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9952f, 0.9994f, 0.9633f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9829f, 0.9120f, 0.8042f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9744f, 0.9296f, 0.9349f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9993f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9998f, 0.9802f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8874f, 0.5963f, 0.9323f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8239f, 0.7625f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6625f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7895f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_4x5[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.8886f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7962f, 0.9052f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8118f, 0.9315f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7247f, 0.8069f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7789f, 0.8308f, 0.8434f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.4129f, 0.4395f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3795f, 0.3370f, 0.1853f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9566f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8585f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8946f, 0.9102f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9502f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9739f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8854f, 0.9554f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9150f, 0.9748f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7849f, 0.8689f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8214f, 0.7729f, 0.8016f, + 1.0000f, 0.9172f, 0.9659f, 0.9781f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9701f, 0.9873f, 0.8394f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9457f, 0.9637f, 0.9334f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9236f, 0.9407f, 0.7395f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6662f, 0.6019f, 0.7169f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5436f, 0.7007f, 0.7907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.0000f, 0.2718f, 0.5740f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.0959f, 0.5888f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9996f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9928f, 0.9995f, 0.9986f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.9998f, 0.9879f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9441f, 0.9773f, 0.9256f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9812f, 0.9789f, 0.8975f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9992f, 0.9949f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9990f, 0.9541f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9690f, 0.9841f, 0.9730f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9425f, 0.9602f, 0.8354f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9001f, 0.6261f, 0.6370f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8549f, 0.8473f, 0.6477f, + 1.0000f, 1.0000f, 0.9648f, 0.9867f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9910f, 0.9884f, 0.9827f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9890f, 0.9670f, 0.9077f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9855f, 0.9276f, 0.6753f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9711f, 0.7668f, 0.5272f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9295f, 0.5087f, 0.9971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9488f, 0.6570f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7537f, 0.9590f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9982f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9848f, 0.9932f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9955f, 0.9936f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9797f, 0.9720f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9680f, 0.9861f, 0.9353f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.9987f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9976f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.9905f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9915f, 0.9919f, 0.9819f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9895f, 0.9389f, 0.8512f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9764f, 0.8917f, 0.4628f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9756f, 0.8262f, 0.6148f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9372f, 0.6843f, 0.6926f, + 1.0000f, 0.9614f, 0.9194f, 0.8723f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9473f, 0.9515f, 0.9625f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7322f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9126f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9991f, 0.9978f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9999f, 0.9579f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9900f, 0.8789f, 0.7088f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9805f, 0.8620f, 0.9026f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8822f, 0.8655f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8166f, 0.9943f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.9997f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9999f, 0.9834f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9215f, 0.5589f, 0.9528f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8756f, 0.7604f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4861f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7467f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_4x6[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7443f, 0.8512f, + 1.0000f, 1.0000f, 1.0000f, 0.8929f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7596f, 0.8882f, + 1.0000f, 1.0000f, 0.8221f, 0.9144f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7051f, 0.6993f, + 1.0000f, 1.0000f, 0.8355f, 0.9440f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7830f, 0.7737f, 0.7389f, + 1.0000f, 1.0000f, 0.7918f, 0.8542f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2729f, 0.4793f, 0.1616f, + 1.0000f, 0.8322f, 0.8760f, 0.8995f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4122f, 0.2349f, 0.0000f, + 1.0000f, 1.0000f, 0.6930f, 0.7495f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7225f, 0.5849f, 0.3642f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9695f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9526f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9550f, 0.9840f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9654f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9824f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9036f, 0.9718f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9414f, 0.9800f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8600f, 0.9466f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8859f, 0.8735f, 0.8451f, + 1.0000f, 0.9271f, 0.9605f, 0.9733f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9177f, 0.9626f, 0.9401f, + 1.0000f, 0.9711f, 0.9893f, 0.8255f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9209f, 0.9616f, 0.6804f, + 1.0000f, 0.9584f, 0.9635f, 0.9110f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5268f, 0.4632f, 0.8387f, + 1.0000f, 0.9161f, 0.9316f, 0.7167f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5749f, 0.6867f, 0.8973f, + 1.0000f, 0.7784f, 0.6674f, 0.8115f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0882f, 0.5113f, 1.0000f, + 1.0000f, 0.6455f, 0.8040f, 0.8628f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3374f, 1.0000f, 1.0000f, + 1.0000f, 0.3093f, 0.5529f, 0.8289f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3896f, 0.8811f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 0.9992f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9997f, 0.9830f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9913f, 0.9538f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9871f, 0.9645f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9991f, 0.9921f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9991f, 0.9514f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9761f, 0.9909f, 0.9851f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9490f, 0.9755f, 0.8835f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9286f, 0.7110f, 0.8187f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8951f, 0.9193f, 0.8077f, + 1.0000f, 1.0000f, 0.9679f, 0.9917f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9794f, 0.9703f, 0.9453f, + 1.0000f, 0.9906f, 0.9941f, 0.9856f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9812f, 0.9561f, 0.7876f, + 1.0000f, 0.9866f, 0.9748f, 0.9127f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9687f, 0.7335f, 0.9478f, + 1.0000f, 0.9898f, 0.9387f, 0.7280f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9074f, 0.6294f, 1.0000f, + 1.0000f, 0.9671f, 0.8419f, 0.5944f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9256f, 0.9960f, 1.0000f, + 1.0000f, 0.9502f, 0.6039f, 0.9985f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6607f, 1.0000f, 1.0000f, + 1.0000f, 0.9775f, 0.6127f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8656f, 0.9225f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9975f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9845f, 0.9946f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.9966f, 0.9955f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, 0.9768f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9740f, 0.9835f, 0.9330f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9986f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.9902f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.9880f, 0.9781f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9889f, 0.9301f, 0.8906f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9787f, 0.9055f, 0.4955f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9806f, 0.8000f, 0.4303f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9015f, 0.6211f, 0.5645f, + 1.0000f, 0.9663f, 0.9240f, 0.8709f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8151f, 1.0000f, 1.0000f, + 1.0000f, 0.9573f, 0.9595f, 0.9726f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9359f, 1.0000f, 1.0000f, + 1.0000f, 0.7644f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9344f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9987f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9983f, 0.9972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9935f, 0.9997f, 0.9373f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9885f, 0.8683f, 0.6534f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9818f, 0.8571f, 0.8786f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7960f, 0.7546f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6376f, 0.9930f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, 0.9999f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9927f, 0.9999f, 0.9875f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9092f, 0.5405f, 0.9427f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8482f, 0.6740f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4469f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7691f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_4x8[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6540f, 0.8090f, 1.0000f, 1.0000f, 0.9047f, 0.9767f, + 1.0000f, 1.0000f, 1.0000f, 0.9273f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6869f, 0.8003f, 0.8742f, 1.0000f, 1.0000f, 0.9569f, 0.9887f, + 1.0000f, 1.0000f, 0.8833f, 0.9454f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7850f, 0.6687f, 0.3938f, 1.0000f, 1.0000f, 0.8390f, 0.8033f, + 1.0000f, 1.0000f, 0.8724f, 0.9732f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6489f, 0.6254f, 0.2363f, 1.0000f, 0.8524f, 0.8851f, 0.8117f, + 1.0000f, 1.0000f, 0.8481f, 0.9106f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1043f, 0.1756f, 0.1402f, 1.0000f, 0.8647f, 0.7274f, 0.3414f, + 1.0000f, 0.9000f, 0.9174f, 0.9444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3601f, 0.0000f, 0.4370f, 1.0000f, 0.7036f, 0.6435f, 0.2612f, + 1.0000f, 1.0000f, 0.8143f, 0.8586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8195f, 0.7196f, 0.5069f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9120f, 0.9463f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8920f, 0.9544f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7626f, 0.7881f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7524f, 0.8413f, 0.3226f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8220f, 0.4960f, 0.0657f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5448f, 0.2826f, 0.2081f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9846f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9693f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9673f, 0.9927f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9858f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9921f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9435f, 0.9866f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9738f, 0.9915f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9200f, 0.9750f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9134f, 0.9308f, 0.8903f, + 1.0000f, 0.9405f, 0.9645f, 0.9687f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8606f, 0.7077f, 0.7420f, 1.0000f, 0.9825f, 0.9880f, 0.9761f, + 1.0000f, 0.9834f, 0.9829f, 0.7943f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7593f, 0.7757f, 0.7724f, 1.0000f, 0.9608f, 0.9800f, 0.8436f, + 1.0000f, 0.9600f, 0.9615f, 0.9319f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3037f, 0.8869f, 1.0000f, 1.0000f, 0.5767f, 0.7455f, 0.9577f, + 1.0000f, 0.9212f, 0.9363f, 0.6953f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5917f, 1.0000f, 1.0000f, 1.0000f, 0.7311f, 0.8761f, 0.9331f, + 1.0000f, 0.8295f, 0.6995f, 0.8815f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4085f, 0.8545f, 1.0000f, + 1.0000f, 0.6911f, 0.8686f, 0.9062f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6734f, 1.0000f, 1.0000f, + 1.0000f, 0.4502f, 0.7157f, 0.9092f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5613f, 0.9491f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8319f, 0.9016f, 0.9160f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9630f, 0.8503f, 0.8459f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4628f, 0.7912f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6124f, 0.8969f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5172f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9997f, 0.9981f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9999f, 0.9638f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, 0.9913f, 0.9285f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9854f, 0.9719f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9995f, 0.9901f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9986f, 0.9395f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9795f, 0.9904f, 0.9850f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9473f, 0.9784f, 0.8627f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9623f, 0.7692f, 0.8705f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9385f, 0.9592f, 0.8367f, + 1.0000f, 1.0000f, 0.9773f, 0.9930f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9518f, 0.9225f, 0.8062f, 1.0000f, 0.9907f, 0.9552f, 0.9261f, + 1.0000f, 0.9968f, 0.9944f, 0.9891f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9561f, 0.8343f, 0.9999f, 1.0000f, 0.9805f, 0.9509f, 0.6058f, + 1.0000f, 0.9961f, 0.9877f, 0.9535f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9425f, 0.9910f, 1.0000f, 1.0000f, 0.9526f, 0.6190f, 0.8270f, + 1.0000f, 0.9942f, 0.9744f, 0.8245f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7559f, 1.0000f, 1.0000f, 1.0000f, 0.8565f, 0.3782f, 1.0000f, + 1.0000f, 0.9815f, 0.8886f, 0.7235f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8779f, 1.0000f, 1.0000f, 1.0000f, 0.9652f, 0.9949f, 1.0000f, + 1.0000f, 0.9755f, 0.7384f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6639f, 1.0000f, 1.0000f, + 1.0000f, 0.9838f, 0.6590f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9077f, 0.9147f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9810f, 0.9353f, 0.6826f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9584f, 0.8953f, 0.6379f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9342f, 0.5271f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7973f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9700f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9237f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9969f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9894f, 0.9951f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9966f, 0.9955f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9869f, 0.9725f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9789f, 0.9873f, 0.9415f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 0.9953f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, 0.9935f, 0.9884f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9680f, 0.9249f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9862f, 0.9374f, 0.4852f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9820f, 0.8170f, 0.4740f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8985f, 0.6780f, 0.5691f, + 1.0000f, 0.9659f, 0.9296f, 0.9031f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5843f, 1.0000f, 1.0000f, + 1.0000f, 0.9482f, 0.9666f, 0.9842f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8797f, 1.0000f, 1.0000f, + 1.0000f, 0.8666f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9713f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9998f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9932f, 0.9990f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9918f, 0.9999f, 0.9187f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9897f, 0.7788f, 0.5362f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9778f, 0.7819f, 0.7347f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7117f, 0.6317f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5530f, 0.9937f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9959f, 1.0000f, 0.9985f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9500f, 0.5989f, 0.9706f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8936f, 0.7490f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4231f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7659f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_4x10[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8566f, 0.9251f, 1.0000f, 1.0000f, 0.9271f, 0.9827f, + 1.0000f, 1.0000f, 1.0000f, 0.9436f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8821f, 0.9344f, 0.9492f, 1.0000f, 1.0000f, 0.9428f, 0.9930f, + 1.0000f, 1.0000f, 0.8766f, 0.9560f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8938f, 0.7784f, 0.3546f, 1.0000f, 1.0000f, 0.8646f, 0.8199f, + 1.0000f, 1.0000f, 0.8737f, 0.9734f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7535f, 0.7283f, 0.2504f, 1.0000f, 0.8807f, 0.9012f, 0.8281f, + 1.0000f, 1.0000f, 0.8874f, 0.9280f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7759f, 0.3657f, 0.2921f, 1.0000f, 0.8913f, 0.7955f, 0.3984f, + 1.0000f, 0.9160f, 0.9412f, 0.9671f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6872f, 0.0745f, 0.6100f, 1.0000f, 0.7706f, 0.7381f, 0.3187f, + 1.0000f, 1.0000f, 0.8301f, 0.8707f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8468f, 0.7733f, 0.5470f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8047f, 0.7932f, 1.0000f, 1.0000f, 0.9395f, 0.9712f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8358f, 0.8692f, 0.8320f, 1.0000f, 1.0000f, 0.9060f, 0.9627f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8024f, 0.6745f, 0.2645f, 1.0000f, 1.0000f, 0.8377f, 0.8630f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7250f, 0.2193f, 0.2008f, 1.0000f, 0.8220f, 0.8926f, 0.4195f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7112f, 0.1026f, 0.4946f, 1.0000f, 0.8598f, 0.6657f, 0.3055f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3767f, 0.1538f, 1.0000f, 1.0000f, 0.6913f, 0.4682f, 0.4591f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5926f, 0.7979f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5866f, 0.6366f, 0.6562f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6994f, 0.4296f, 0.1289f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6701f, 0.3312f, 0.3434f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0378f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1783f, 0.2350f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9921f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9784f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9831f, 0.9939f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9614f, 0.9924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9884f, 0.9951f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9420f, 0.9815f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9387f, 0.9461f, 0.8661f, + 1.0000f, 0.9567f, 0.9659f, 0.9652f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8834f, 0.8339f, 0.9000f, 1.0000f, 0.9857f, 0.9896f, 0.9760f, + 1.0000f, 0.9901f, 0.9819f, 0.7622f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8135f, 0.9083f, 0.8900f, 1.0000f, 0.9594f, 0.9798f, 0.8002f, + 1.0000f, 0.9677f, 0.9515f, 0.8861f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5178f, 0.8550f, 1.0000f, 1.0000f, 0.5985f, 0.7810f, 0.9500f, + 1.0000f, 0.9105f, 0.9201f, 0.6788f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7316f, 1.0000f, 1.0000f, 1.0000f, 0.7650f, 0.8534f, 0.9469f, + 1.0000f, 0.8485f, 0.7476f, 0.9036f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5025f, 0.9072f, 1.0000f, + 1.0000f, 0.7678f, 0.8793f, 0.9221f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7594f, 1.0000f, 1.0000f, + 1.0000f, 0.4772f, 0.7835f, 0.9191f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6044f, 0.9689f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6465f, 0.7034f, 0.9231f, 1.0000f, 0.8451f, 0.9308f, 0.9665f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7349f, 0.8241f, 0.9445f, 1.0000f, 0.9850f, 0.8976f, 0.9149f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6314f, 1.0000f, 1.0000f, 1.0000f, 0.6610f, 0.9261f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7860f, 0.9379f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7147f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5326f, 0.6155f, 0.9573f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5253f, 0.8582f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9988f, 0.9974f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9998f, 0.9530f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9839f, 0.8722f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9770f, 0.9353f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9991f, 0.9890f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9993f, 0.9139f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9854f, 0.9919f, 0.9878f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9545f, 0.9846f, 0.8677f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9640f, 0.7446f, 0.8501f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9241f, 0.9476f, 0.8432f, + 1.0000f, 1.0000f, 0.9779f, 0.9978f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9587f, 0.8887f, 0.6209f, 1.0000f, 0.9871f, 0.9553f, 0.9317f, + 1.0000f, 0.9946f, 0.9959f, 0.9928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9181f, 0.6830f, 0.9999f, 1.0000f, 0.9750f, 0.9335f, 0.5610f, + 1.0000f, 0.9960f, 0.9916f, 0.9707f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9048f, 0.9484f, 1.0000f, 1.0000f, 0.9507f, 0.6415f, 0.7506f, + 1.0000f, 0.9914f, 0.9739f, 0.8614f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5398f, 1.0000f, 1.0000f, 1.0000f, 0.8517f, 0.2785f, 1.0000f, + 1.0000f, 0.9835f, 0.9299f, 0.8069f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9601f, 1.0000f, 1.0000f, 1.0000f, 0.9684f, 0.9926f, 1.0000f, + 1.0000f, 0.9864f, 0.8414f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7414f, 1.0000f, 1.0000f, + 1.0000f, 0.9806f, 0.7565f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9289f, 0.9362f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9646f, 0.8156f, 0.9811f, 1.0000f, 0.9843f, 0.9128f, 0.7181f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9211f, 0.6953f, 1.0000f, 1.0000f, 0.9453f, 0.9094f, 0.5542f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9326f, 1.0000f, 1.0000f, 1.0000f, 0.9701f, 0.4859f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7216f, 1.0000f, 1.0000f, 1.0000f, 0.7884f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9789f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8848f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9580f, 0.8752f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9370f, 0.9620f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9765f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9904f, 0.9985f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9935f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9887f, 0.9981f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9977f, 0.9962f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9723f, 0.9793f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9744f, 0.9874f, 0.8964f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9950f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9971f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9976f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 0.9937f, 0.9941f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9909f, 0.9718f, 0.9523f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9881f, 0.9607f, 0.5805f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9868f, 0.8396f, 0.4496f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8780f, 0.7073f, 0.5743f, + 1.0000f, 0.9729f, 0.9404f, 0.9117f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4398f, 1.0000f, 1.0000f, + 1.0000f, 0.9695f, 0.9633f, 0.9893f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7908f, 1.0000f, 1.0000f, + 1.0000f, 0.8951f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9823f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9997f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9906f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, 0.9984f, 0.9955f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9899f, 0.9999f, 0.9024f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.8113f, 0.5679f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9775f, 0.8261f, 0.8091f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6262f, 0.4091f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3877f, 0.9802f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9911f, 1.0000f, 0.9982f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9538f, 0.6514f, 0.9755f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9171f, 0.8178f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5103f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8988f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_4x12[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8570f, 0.9351f, 1.0000f, 1.0000f, 0.9461f, 0.9884f, + 1.0000f, 1.0000f, 1.0000f, 0.9476f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8944f, 0.9376f, 0.9581f, 1.0000f, 1.0000f, 0.9811f, 0.9855f, + 1.0000f, 1.0000f, 0.8777f, 0.9658f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9121f, 0.8362f, 0.4335f, 1.0000f, 1.0000f, 0.8910f, 0.8445f, + 1.0000f, 1.0000f, 0.9001f, 0.9751f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7894f, 0.7758f, 0.3577f, 1.0000f, 0.9024f, 0.9256f, 0.8509f, + 1.0000f, 1.0000f, 0.9301f, 0.9384f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7873f, 0.5440f, 0.4410f, 1.0000f, 0.9013f, 0.8413f, 0.4701f, + 1.0000f, 0.9468f, 0.9618f, 0.9630f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7346f, 0.1421f, 0.7373f, 1.0000f, 0.8184f, 0.8105f, 0.3846f, + 1.0000f, 1.0000f, 0.8656f, 0.9141f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8886f, 0.8002f, 0.6091f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5378f, 1.0000f, 1.0000f, 1.0000f, 0.6809f, 1.0000f, 0.8396f, 0.8125f, 0.5731f, 1.0000f, 0.9438f, 0.9669f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6042f, 1.0000f, 1.0000f, 1.0000f, 0.6916f, 0.8311f, 0.8752f, 0.8585f, 0.3390f, 1.0000f, 0.9247f, 0.9600f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6616f, 1.0000f, 1.0000f, 1.0000f, 0.1980f, 0.8165f, 0.7143f, 0.3757f, 0.6363f, 1.0000f, 0.8294f, 0.8477f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4913f, 1.0000f, 1.0000f, 1.0000f, 0.1094f, 0.7507f, 0.2782f, 0.2886f, 1.0000f, 0.8222f, 0.8898f, 0.3091f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0310f, 1.0000f, 1.0000f, 1.0000f, 0.5560f, 0.7686f, 0.1850f, 0.6319f, 1.0000f, 0.9191f, 0.7050f, 0.2461f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5675f, 0.2231f, 1.0000f, 1.0000f, 0.6985f, 0.4180f, 0.4557f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8145f, 0.8826f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8023f, 0.7710f, 0.6274f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8328f, 0.5182f, 0.1259f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7290f, 0.2349f, 0.4100f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6951f, 0.0862f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3292f, 0.4773f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9896f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9874f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9865f, 0.9955f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7113f, 0.7782f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7981f, 0.8493f, 0.4484f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7082f, 0.2106f, 0.2571f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6183f, 0.0618f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4259f, 0.1570f, 1.0000f, 1.0000f, 1.0000f, 0.9717f, 0.9958f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1715f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9922f, 0.9966f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9391f, 0.9848f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9574f, 0.9675f, 0.8990f, + 1.0000f, 0.9841f, 0.9587f, 0.9624f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9034f, 0.8540f, 0.9309f, 1.0000f, 0.9732f, 0.9837f, 0.9686f, + 1.0000f, 0.9912f, 0.9827f, 0.7481f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8276f, 0.9399f, 0.8790f, 1.0000f, 0.9343f, 0.9760f, 0.7612f, + 1.0000f, 0.9746f, 0.9612f, 0.8967f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6406f, 0.8863f, 1.0000f, 1.0000f, 0.6138f, 0.8065f, 0.9265f, + 1.0000f, 0.9359f, 0.9292f, 0.6733f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7938f, 1.0000f, 1.0000f, 1.0000f, 0.7637f, 0.8599f, 0.9680f, + 1.0000f, 0.8670f, 0.7232f, 0.8979f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5945f, 0.9483f, 1.0000f, + 1.0000f, 0.7661f, 0.8738f, 0.9423f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8345f, 1.0000f, 1.0000f, + 1.0000f, 0.4981f, 0.8429f, 0.9533f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6695f, 0.9795f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4017f, 1.0000f, 1.0000f, 1.0000f, 0.9707f, 0.6880f, 0.7828f, 0.9519f, 1.0000f, 0.8203f, 0.9162f, 0.9505f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6229f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8044f, 0.8851f, 0.9727f, 1.0000f, 0.9770f, 0.8628f, 0.8711f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6656f, 1.0000f, 1.0000f, 1.0000f, 0.5842f, 0.9099f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7734f, 0.9078f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7401f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5116f, 0.7916f, 0.9498f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6492f, 0.9741f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9971f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9996f, 0.9948f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9989f, 0.9219f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9756f, 0.8524f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9653f, 0.9446f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5617f, 0.8697f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7261f, 0.9702f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9994f, 0.9917f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9986f, 0.9238f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9799f, 0.9920f, 0.9851f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9554f, 0.9787f, 0.8555f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9696f, 0.7805f, 0.8614f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9318f, 0.9540f, 0.8933f, + 1.0000f, 1.0000f, 0.9815f, 0.9981f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9326f, 0.8764f, 0.5894f, 1.0000f, 0.9915f, 0.9407f, 0.9200f, + 1.0000f, 0.9940f, 0.9982f, 0.9946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9152f, 0.6449f, 1.0000f, 1.0000f, 0.9722f, 0.9526f, 0.5249f, + 1.0000f, 0.9960f, 0.9893f, 0.9774f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8956f, 0.9210f, 1.0000f, 1.0000f, 0.9647f, 0.6845f, 0.7586f, + 1.0000f, 0.9951f, 0.9868f, 0.8874f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4843f, 1.0000f, 1.0000f, 1.0000f, 0.8724f, 0.2989f, 1.0000f, + 1.0000f, 0.9877f, 0.9453f, 0.8258f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9593f, 1.0000f, 1.0000f, 1.0000f, 0.9779f, 0.9931f, 1.0000f, + 1.0000f, 0.9834f, 0.8814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7850f, 1.0000f, 1.0000f, + 1.0000f, 0.9858f, 0.8240f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9512f, 0.9791f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9664f, 1.0000f, 1.0000f, 1.0000f, 0.9942f, 0.9547f, 0.8085f, 0.9335f, 1.0000f, 0.9823f, 0.8802f, 0.6575f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9283f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9067f, 0.5502f, 1.0000f, 1.0000f, 0.9088f, 0.8642f, 0.3484f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9228f, 1.0000f, 1.0000f, 1.0000f, 0.9415f, 0.3668f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5994f, 1.0000f, 1.0000f, 1.0000f, 0.7560f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9636f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8461f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9561f, 0.7018f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8921f, 0.9171f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9368f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9991f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9808f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9927f, 0.9962f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9887f, 0.9933f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9929f, 0.9956f, 0.9975f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9898f, 0.9804f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9890f, 0.9925f, 0.9274f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9131f, 0.7534f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9987f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9110f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9949f, 0.9936f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9737f, 0.9567f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9830f, 0.9641f, 0.5787f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9844f, 0.8379f, 0.5048f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8839f, 0.7455f, 0.6771f, + 1.0000f, 0.9819f, 0.9430f, 0.9181f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2677f, 1.0000f, 1.0000f, + 1.0000f, 0.9712f, 0.9691f, 0.9880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7202f, 1.0000f, 1.0000f, + 1.0000f, 0.9490f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9974f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9998f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 1.0000f, 0.9904f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9907f, 0.9992f, 0.9944f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, 0.9998f, 0.9056f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9909f, 0.7959f, 0.4630f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9765f, 0.7173f, 0.7318f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6533f, 0.3193f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3931f, 0.9783f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 1.0000f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9871f, 0.7428f, 0.9901f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9606f, 0.9045f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5315f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8683f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_5x4[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9496f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8709f, 0.9575f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9171f, 0.9748f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7120f, 0.8199f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7195f, 0.8475f, 0.8778f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.8093f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7545f, 0.8939f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7609f, 0.8637f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8146f, 0.7796f, 0.7858f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.4100f, 0.4583f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3782f, 0.3366f, 0.1850f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9259f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9468f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9789f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8600f, 0.9338f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8996f, 0.9424f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9871f, 0.9983f, 0.9979f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9960f, 0.9996f, 0.9853f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9691f, 0.9797f, 0.9711f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9375f, 0.9680f, 0.8560f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7043f, 0.5964f, 0.6432f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6090f, 0.6709f, 0.7735f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9279f, 0.9550f, 0.8744f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9701f, 0.9537f, 0.8386f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8879f, 0.5694f, 0.6328f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8247f, 0.8295f, 0.6886f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.0000f, 0.2712f, 0.5397f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.0963f, 0.5833f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9937f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9440f, 0.9832f, 0.9914f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9756f, 0.9930f, 0.9075f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9993f, 0.9943f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9995f, 0.9612f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9563f, 0.9781f, 0.9482f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9509f, 0.9600f, 0.7919f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9846f, 0.9901f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9955f, 0.9949f, 0.9922f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9891f, 0.9319f, 0.8673f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9773f, 0.8910f, 0.4347f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9635f, 0.8035f, 0.5226f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9148f, 0.5045f, 0.9972f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9839f, 0.9624f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9647f, 0.9818f, 0.8812f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9739f, 0.8431f, 0.6214f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9409f, 0.6619f, 0.6966f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9523f, 0.6526f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7410f, 0.9658f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9982f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9720f, 0.9905f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, 0.9876f, 0.9910f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9987f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9918f, 0.9896f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9865f, 0.9881f, 0.9811f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9886f, 0.9669f, 0.9238f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9804f, 0.9392f, 0.6799f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9926f, 0.9100f, 0.7478f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9825f, 0.9023f, 0.9216f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4818f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7267f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8518f, 0.8968f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8341f, 0.9952f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9991f, 0.9974f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, 0.9995f, 0.9588f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9859f, 0.9049f, 0.7977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9765f, 0.9299f, 0.9357f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9994f, 0.9986f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9999f, 0.9730f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9124f, 0.5547f, 0.9454f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8846f, 0.7672f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7339f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9194f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_5x5[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9673f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8974f, 0.9705f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9498f, 0.9880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7791f, 0.9035f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8333f, 0.9204f, 0.9408f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6652f, 0.7473f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6369f, 0.6289f, 0.4604f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.7754f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6903f, 0.8953f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7639f, 0.8932f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8120f, 0.8089f, 0.7862f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6844f, 0.7250f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6955f, 0.6206f, 0.3520f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2657f, 0.4988f, 0.1727f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5175f, 0.1199f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9727f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8910f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9055f, 0.9093f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9665f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9131f, 0.9740f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9510f, 0.9875f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8027f, 0.9112f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8448f, 0.8392f, 0.8528f, + 1.0000f, 0.9910f, 0.9977f, 0.9974f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9976f, 0.9998f, 0.9802f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9772f, 0.9892f, 0.9845f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9568f, 0.9747f, 0.8704f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7678f, 0.7431f, 0.8728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6783f, 0.8888f, 0.8421f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3271f, 0.5343f, 0.8182f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3750f, 0.8502f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9168f, 0.9522f, 0.8304f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9713f, 0.9448f, 0.7598f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9290f, 0.6512f, 0.7056f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8798f, 0.8630f, 0.7515f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3020f, 0.6100f, 0.8243f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4798f, 0.8866f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2212f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4198f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9934f, 0.9986f, 0.9991f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9997f, 0.9813f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9435f, 0.9657f, 0.9186f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9835f, 0.9734f, 0.8752f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9993f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9990f, 0.9931f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9996f, 0.9600f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9766f, 0.9900f, 0.9870f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9620f, 0.9790f, 0.8680f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9557f, 0.7202f, 0.7298f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9274f, 0.9150f, 0.7556f, + 1.0000f, 1.0000f, 0.9830f, 0.9888f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9951f, 0.9955f, 0.9953f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9913f, 0.9590f, 0.9222f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9796f, 0.9257f, 0.5728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9630f, 0.7006f, 0.3980f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8775f, 0.4409f, 0.9903f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9697f, 0.6582f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8058f, 0.9074f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9784f, 0.9681f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9461f, 0.9778f, 0.8605f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9856f, 0.8995f, 0.7344f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9648f, 0.7717f, 0.8475f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9689f, 0.6442f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7962f, 0.9336f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9421f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8151f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9984f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9865f, 0.9969f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9946f, 0.9958f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9760f, 0.9819f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9610f, 0.9840f, 0.9546f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9987f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9936f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9928f, 0.9919f, 0.9851f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9896f, 0.9579f, 0.9239f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9753f, 0.9305f, 0.5978f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9808f, 0.9015f, 0.7154f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9639f, 0.8213f, 0.7929f, + 1.0000f, 0.9922f, 0.9395f, 0.7388f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9925f, 0.9321f, 0.9534f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5473f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7995f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8363f, 0.9351f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8274f, 0.9983f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9996f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 1.0000f, 0.9916f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9941f, 0.9995f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.9999f, 0.9486f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9884f, 0.8554f, 0.6717f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9824f, 0.8655f, 0.9366f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8844f, 0.8580f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7828f, 0.9960f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 0.9997f, 0.9978f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.9994f, 0.9720f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9381f, 0.5602f, 0.9473f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8821f, 0.7105f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5854f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7896f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_5x6[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7676f, 0.8675f, + 1.0000f, 1.0000f, 1.0000f, 0.9864f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7053f, 0.9024f, + 1.0000f, 1.0000f, 0.9386f, 0.9764f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7801f, 0.7480f, + 1.0000f, 1.0000f, 0.9611f, 0.9896f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8218f, 0.8480f, 0.8548f, + 1.0000f, 1.0000f, 0.8503f, 0.9257f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8005f, 0.6960f, 0.3353f, + 1.0000f, 0.8947f, 0.9459f, 0.9561f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6706f, 0.6054f, 0.2768f, + 1.0000f, 1.0000f, 0.7892f, 0.8033f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2041f, 0.1229f, 0.0000f, + 1.0000f, 0.7546f, 0.6863f, 0.4459f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3735f, 0.1652f, 0.2428f, + 1.0000f, 1.0000f, 1.0000f, 0.8695f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8914f, 0.9111f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8267f, 0.9097f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8613f, 0.8655f, 0.8194f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7412f, 0.8060f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7739f, 0.6811f, 0.4847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7978f, 0.6426f, 0.3562f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6252f, 0.4722f, 0.0797f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9822f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9675f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9641f, 0.9852f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9826f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9889f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9352f, 0.9793f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9648f, 0.9912f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8994f, 0.9701f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9083f, 0.9192f, 0.8846f, + 1.0000f, 0.9938f, 0.9983f, 0.9985f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9232f, 0.9570f, 0.9270f, + 1.0000f, 0.9993f, 0.9999f, 0.9808f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9219f, 0.9543f, 0.6541f, + 1.0000f, 0.9753f, 0.9879f, 0.9779f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6188f, 0.5981f, 0.9069f, + 1.0000f, 0.9449f, 0.9689f, 0.8593f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7008f, 0.7950f, 0.9340f, + 1.0000f, 0.8292f, 0.8315f, 0.9166f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3094f, 0.7513f, 1.0000f, + 1.0000f, 0.7303f, 0.9293f, 0.8880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5724f, 1.0000f, 1.0000f, + 1.0000f, 0.4322f, 0.7265f, 0.8387f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5815f, 0.9363f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9054f, 0.9516f, 0.8115f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9774f, 0.9329f, 0.7377f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9305f, 0.6369f, 0.7226f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8734f, 0.8457f, 0.7645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4184f, 0.6759f, 0.8897f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5631f, 0.9375f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4043f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6122f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, 0.9991f, 0.9981f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9999f, 0.9798f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, 0.9918f, 0.9469f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9886f, 0.9655f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9996f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9993f, 0.9926f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9995f, 0.9430f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9844f, 0.9934f, 0.9883f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9595f, 0.9860f, 0.8930f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9626f, 0.7580f, 0.8715f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9419f, 0.9587f, 0.8754f, + 1.0000f, 1.0000f, 0.9736f, 0.9956f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9784f, 0.9669f, 0.9552f, + 1.0000f, 0.9945f, 0.9948f, 0.9976f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9682f, 0.9478f, 0.7832f, + 1.0000f, 0.9921f, 0.9603f, 0.9039f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9742f, 0.8434f, 0.9695f, + 1.0000f, 0.9789f, 0.9282f, 0.5534f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9440f, 0.7141f, 1.0000f, + 1.0000f, 0.9634f, 0.7446f, 0.3889f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9497f, 0.9903f, 1.0000f, + 1.0000f, 0.8828f, 0.4971f, 0.9909f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6912f, 1.0000f, 1.0000f, + 1.0000f, 0.9507f, 0.4594f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8978f, 1.0000f, 1.0000f, + 1.0000f, 0.7708f, 0.7612f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9835f, 0.9725f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9534f, 0.9813f, 0.8863f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9747f, 0.9152f, 0.7862f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9731f, 0.8243f, 0.8634f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9719f, 0.7097f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8772f, 0.9179f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9713f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8142f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9959f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9831f, 0.9943f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9929f, 0.9964f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9803f, 0.9868f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9817f, 0.9946f, 0.9408f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.9986f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9967f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9931f, 0.9952f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.9875f, 0.9769f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9893f, 0.9525f, 0.9206f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9707f, 0.9245f, 0.5433f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9839f, 0.8571f, 0.5900f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9317f, 0.7185f, 0.6652f, + 1.0000f, 0.9941f, 0.9488f, 0.7922f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8363f, 1.0000f, 1.0000f, + 1.0000f, 0.9900f, 0.9578f, 0.9662f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9618f, 1.0000f, 1.0000f, + 1.0000f, 0.5093f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8410f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8339f, 0.9397f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8526f, 0.9975f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9998f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 1.0000f, 0.9872f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9989f, 0.9954f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9848f, 0.9999f, 0.9139f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9915f, 0.8791f, 0.6311f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9856f, 0.8810f, 0.8963f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7770f, 0.7341f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6597f, 0.9984f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9950f, 0.9997f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 1.0000f, 0.9758f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9009f, 0.5208f, 0.9125f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8168f, 0.6484f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5321f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8087f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_5x8[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7170f, 0.8180f, 1.0000f, 1.0000f, 0.9306f, 0.9785f, + 1.0000f, 1.0000f, 1.0000f, 0.9950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6965f, 0.8011f, 0.8628f, 1.0000f, 1.0000f, 0.9641f, 0.9929f, + 1.0000f, 1.0000f, 0.9698f, 0.9907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8033f, 0.7695f, 0.5461f, 1.0000f, 1.0000f, 0.8906f, 0.8389f, + 1.0000f, 1.0000f, 0.9849f, 0.9943f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7269f, 0.7332f, 0.3842f, 1.0000f, 0.9127f, 0.9202f, 0.8794f, + 1.0000f, 1.0000f, 0.9070f, 0.9559f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7034f, 0.3723f, 0.2234f, 1.0000f, 0.8946f, 0.7922f, 0.3594f, + 1.0000f, 0.9242f, 0.9635f, 0.9682f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6392f, 0.0795f, 0.6486f, 1.0000f, 0.7642f, 0.7103f, 0.3052f, + 1.0000f, 1.0000f, 0.8823f, 0.8660f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0406f, 0.0000f, 1.0000f, 1.0000f, 0.7898f, 0.3960f, 0.1575f, + 1.0000f, 0.8530f, 0.7721f, 0.5161f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1334f, 0.2435f, 1.0000f, 1.0000f, 0.7069f, 0.3461f, 0.4915f, + 1.0000f, 1.0000f, 1.0000f, 0.9138f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9288f, 0.9617f, + 1.0000f, 1.0000f, 0.9366f, 0.9407f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9160f, 0.9468f, + 1.0000f, 1.0000f, 0.8933f, 0.9340f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8139f, 0.8408f, + 1.0000f, 0.9212f, 0.9105f, 0.8580f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8352f, 0.8809f, 0.4176f, + 1.0000f, 1.0000f, 0.8220f, 0.8893f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8780f, 0.5863f, 0.1090f, + 1.0000f, 0.8426f, 0.7589f, 0.5668f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6343f, 0.3327f, 0.2762f, + 1.0000f, 0.8720f, 0.7451f, 0.5388f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6818f, 0.2028f, 0.2913f, + 1.0000f, 0.7507f, 0.6293f, 0.2599f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4473f, 0.1808f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9896f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9781f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9823f, 0.9956f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9937f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9954f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9579f, 0.9919f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9838f, 0.9931f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9391f, 0.9827f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9374f, 0.9518f, 0.9034f, + 1.0000f, 0.9982f, 0.9996f, 0.9986f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8612f, 0.7136f, 0.7301f, 1.0000f, 0.9801f, 0.9909f, 0.9734f, + 1.0000f, 0.9995f, 0.9993f, 0.9789f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7669f, 0.7422f, 0.7773f, 1.0000f, 0.9664f, 0.9820f, 0.8240f, + 1.0000f, 0.9769f, 0.9901f, 0.9773f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4378f, 0.9438f, 1.0000f, 1.0000f, 0.6531f, 0.8119f, 0.9692f, + 1.0000f, 0.9460f, 0.9793f, 0.8750f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6780f, 1.0000f, 1.0000f, 1.0000f, 0.8054f, 0.9116f, 0.9629f, + 1.0000f, 0.8596f, 0.8201f, 0.9399f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5237f, 0.8644f, 1.0000f, + 1.0000f, 0.7824f, 0.9357f, 0.9022f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7534f, 1.0000f, 1.0000f, + 1.0000f, 0.4659f, 0.8496f, 0.8997f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6741f, 0.9747f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8972f, 0.9423f, 0.7945f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8334f, 0.9171f, 0.9222f, + 1.0000f, 0.9805f, 0.9182f, 0.6930f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9687f, 0.8735f, 0.8563f, + 1.0000f, 0.9415f, 0.6702f, 0.7850f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5799f, 0.8444f, 1.0000f, + 1.0000f, 0.8879f, 0.8461f, 0.8160f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7000f, 0.9383f, 1.0000f, + 1.0000f, 0.4831f, 0.7799f, 0.9315f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5602f, 1.0000f, 1.0000f, + 1.0000f, 0.6191f, 0.9572f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6242f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7967f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9988f, 0.9972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9997f, 0.9539f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9890f, 0.9192f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9869f, 0.9724f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9995f, 0.9914f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9987f, 0.9232f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9835f, 0.9933f, 0.9893f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9511f, 0.9812f, 0.8705f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9708f, 0.8076f, 0.9081f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9532f, 0.9703f, 0.8690f, + 1.0000f, 1.0000f, 0.9884f, 0.9991f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9445f, 0.9332f, 0.8297f, 1.0000f, 0.9856f, 0.9760f, 0.9605f, + 1.0000f, 0.9981f, 0.9959f, 0.9989f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9623f, 0.8278f, 0.9999f, 1.0000f, 0.9872f, 0.9552f, 0.6660f, + 1.0000f, 0.9979f, 0.9899f, 0.9525f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9676f, 0.9922f, 1.0000f, 1.0000f, 0.9598f, 0.6894f, 0.8513f, + 1.0000f, 0.9912f, 0.9430f, 0.6139f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8546f, 1.0000f, 1.0000f, 1.0000f, 0.8985f, 0.4070f, 1.0000f, + 1.0000f, 0.9752f, 0.8259f, 0.4566f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9475f, 1.0000f, 1.0000f, 1.0000f, 0.9058f, 0.9453f, 1.0000f, + 1.0000f, 0.8919f, 0.5734f, 0.9973f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4998f, 1.0000f, 1.0000f, + 1.0000f, 0.9566f, 0.4281f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9504f, 1.0000f, 1.0000f, + 1.0000f, 0.8098f, 0.6575f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9887f, 0.9756f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9875f, 0.9647f, 0.7479f, + 1.0000f, 0.9653f, 0.9842f, 0.8959f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9670f, 0.9270f, 0.7203f, + 1.0000f, 0.9878f, 0.9483f, 0.8865f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9545f, 0.5978f, 1.0000f, + 1.0000f, 0.9765f, 0.9046f, 0.9490f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8479f, 1.0000f, 1.0000f, + 1.0000f, 0.9777f, 0.7875f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9093f, 1.0000f, 1.0000f, + 1.0000f, 0.9279f, 0.9585f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7362f, 1.0000f, 1.0000f, + 1.0000f, 0.9743f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8315f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, 0.9980f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 0.9969f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9852f, 0.9926f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9960f, 0.9963f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9816f, 0.9845f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9831f, 0.9882f, 0.9592f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 0.9996f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9946f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9966f, 0.9924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9659f, 0.9297f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9714f, 0.9611f, 0.4745f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9862f, 0.8371f, 0.5080f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8851f, 0.7393f, 0.6035f, + 1.0000f, 0.9976f, 0.9808f, 0.9149f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6439f, 1.0000f, 1.0000f, + 1.0000f, 0.9965f, 0.9729f, 0.9917f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9251f, 1.0000f, 1.0000f, + 1.0000f, 0.5922f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9349f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8837f, 0.9497f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8765f, 0.9992f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9994f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 1.0000f, 0.9738f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9797f, 0.9985f, 0.9935f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9904f, 0.9999f, 0.9010f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9866f, 0.7747f, 0.5533f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9719f, 0.7989f, 0.7562f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7616f, 0.6618f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6087f, 0.9975f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 1.0000f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9941f, 0.9998f, 0.9859f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9261f, 0.5314f, 0.9323f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8675f, 0.6856f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3191f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7236f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_5x10[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8828f, 0.9380f, 1.0000f, 1.0000f, 0.9474f, 0.9876f, + 1.0000f, 1.0000f, 1.0000f, 0.9969f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9001f, 0.9507f, 0.9435f, 1.0000f, 1.0000f, 0.9629f, 0.9920f, + 1.0000f, 1.0000f, 0.9747f, 0.9932f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9144f, 0.8460f, 0.4607f, 1.0000f, 1.0000f, 0.8863f, 0.8325f, + 1.0000f, 1.0000f, 0.9864f, 0.9957f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8000f, 0.7799f, 0.3655f, 1.0000f, 0.9060f, 0.9291f, 0.8517f, + 1.0000f, 1.0000f, 0.9234f, 0.9619f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7902f, 0.3573f, 0.2754f, 1.0000f, 0.9172f, 0.8197f, 0.3042f, + 1.0000f, 0.9550f, 0.9704f, 0.9787f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7244f, 0.0600f, 0.6069f, 1.0000f, 0.7961f, 0.7590f, 0.2856f, + 1.0000f, 1.0000f, 0.8770f, 0.8851f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5834f, 0.1053f, 1.0000f, 1.0000f, 0.8246f, 0.4735f, 0.1961f, + 1.0000f, 0.8503f, 0.7861f, 0.4860f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2949f, 0.5229f, 1.0000f, 1.0000f, 0.7710f, 0.3896f, 0.6023f, + 1.0000f, 1.0000f, 1.0000f, 0.9275f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8614f, 0.8180f, 1.0000f, 1.0000f, 0.9461f, 0.9783f, + 1.0000f, 1.0000f, 0.9358f, 0.9421f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8474f, 0.8885f, 0.8356f, 1.0000f, 1.0000f, 0.9298f, 0.9798f, + 1.0000f, 1.0000f, 0.9126f, 0.9415f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8430f, 0.7410f, 0.3736f, 1.0000f, 1.0000f, 0.8719f, 0.8928f, + 1.0000f, 0.9321f, 0.9098f, 0.8586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7733f, 0.3401f, 0.2651f, 1.0000f, 0.8745f, 0.9217f, 0.4542f, + 1.0000f, 1.0000f, 0.8654f, 0.9107f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7686f, 0.1264f, 0.5169f, 1.0000f, 0.9040f, 0.7056f, 0.2329f, + 1.0000f, 0.8840f, 0.8074f, 0.6534f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5046f, 0.1459f, 1.0000f, 1.0000f, 0.7120f, 0.3314f, 0.5107f, + 1.0000f, 0.8874f, 0.7841f, 0.5784f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4128f, 0.2091f, 1.0000f, 1.0000f, 0.7514f, 0.3225f, 0.5682f, + 1.0000f, 0.7778f, 0.6958f, 0.2441f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1650f, 1.0000f, 1.0000f, 1.0000f, 0.6114f, 0.3816f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6415f, 0.8110f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5576f, 0.6495f, 0.6684f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7302f, 0.5465f, 0.1821f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7273f, 0.4671f, 0.4923f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6203f, 0.0829f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2546f, 0.4985f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9947f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9813f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0322f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9867f, 0.9970f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9794f, 0.9904f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9858f, 0.9968f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9428f, 0.9840f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9556f, 0.9613f, 0.8896f, + 1.0000f, 0.9990f, 0.9988f, 0.9993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9117f, 0.8401f, 0.9079f, 1.0000f, 0.9827f, 0.9897f, 0.9767f, + 1.0000f, 0.9996f, 0.9998f, 0.9881f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8386f, 0.9283f, 0.9242f, 1.0000f, 0.9579f, 0.9771f, 0.8092f, + 1.0000f, 0.9779f, 0.9849f, 0.9759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6247f, 0.9069f, 1.0000f, 1.0000f, 0.6374f, 0.8145f, 0.9365f, + 1.0000f, 0.9487f, 0.9717f, 0.8531f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8038f, 1.0000f, 1.0000f, 1.0000f, 0.7981f, 0.8817f, 0.9730f, + 1.0000f, 0.9030f, 0.8694f, 0.9680f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5882f, 0.8805f, 1.0000f, + 1.0000f, 0.8230f, 0.9650f, 0.9538f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7941f, 1.0000f, 1.0000f, + 1.0000f, 0.3975f, 0.8668f, 0.8960f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7088f, 0.9685f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8781f, 0.9441f, 0.7882f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6925f, 0.7213f, 0.9250f, 1.0000f, 0.8707f, 0.9344f, 0.9722f, + 1.0000f, 0.9873f, 0.9154f, 0.6991f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7663f, 0.8416f, 0.9635f, 1.0000f, 0.9861f, 0.9135f, 0.9190f, + 1.0000f, 0.9267f, 0.6720f, 0.7540f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7488f, 1.0000f, 1.0000f, 1.0000f, 0.7182f, 0.9448f, 1.0000f, + 1.0000f, 0.8573f, 0.8163f, 0.8056f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8489f, 0.9739f, 1.0000f, + 1.0000f, 0.5288f, 0.8278f, 0.9624f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6611f, 1.0000f, 1.0000f, + 1.0000f, 0.6823f, 0.9775f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6891f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8627f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4478f, 0.6290f, 0.9660f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5629f, 0.8641f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 0.9986f, 0.9960f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9998f, 0.9306f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9763f, 0.8559f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9690f, 0.9329f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9988f, 0.9892f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9994f, 0.9011f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9846f, 0.9934f, 0.9928f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9591f, 0.9902f, 0.8732f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9665f, 0.7755f, 0.8545f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9468f, 0.9525f, 0.8371f, + 1.0000f, 1.0000f, 0.9855f, 0.9995f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9574f, 0.8980f, 0.7024f, 1.0000f, 0.9895f, 0.9806f, 0.9562f, + 1.0000f, 0.9980f, 0.9991f, 0.9994f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9455f, 0.7330f, 1.0000f, 1.0000f, 0.9823f, 0.9640f, 0.5930f, + 1.0000f, 0.9955f, 0.9843f, 0.9500f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9181f, 0.9481f, 1.0000f, 1.0000f, 0.9351f, 0.6857f, 0.7436f, + 1.0000f, 0.9899f, 0.9791f, 0.6789f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6159f, 1.0000f, 1.0000f, 1.0000f, 0.8758f, 0.2214f, 1.0000f, + 1.0000f, 0.9918f, 0.8793f, 0.5977f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9020f, 1.0000f, 1.0000f, 1.0000f, 0.8445f, 0.9050f, 1.0000f, + 1.0000f, 0.9258f, 0.6648f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4411f, 1.0000f, 1.0000f, + 1.0000f, 0.9694f, 0.4342f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9519f, 1.0000f, 1.0000f, + 1.0000f, 0.7921f, 0.7151f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9852f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9907f, 0.9816f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9675f, 0.8681f, 0.9926f, 1.0000f, 0.9916f, 0.9387f, 0.7639f, + 1.0000f, 0.9585f, 0.9914f, 0.8991f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9372f, 0.7615f, 1.0000f, 1.0000f, 0.9494f, 0.9088f, 0.6332f, + 1.0000f, 0.9909f, 0.9645f, 0.8917f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9655f, 1.0000f, 1.0000f, 1.0000f, 0.9544f, 0.4798f, 1.0000f, + 1.0000f, 0.9836f, 0.9225f, 0.9531f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7383f, 1.0000f, 1.0000f, 1.0000f, 0.8128f, 1.0000f, 1.0000f, + 1.0000f, 0.9820f, 0.8263f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9199f, 1.0000f, 1.0000f, + 1.0000f, 0.9568f, 0.9870f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6573f, 1.0000f, 1.0000f, + 1.0000f, 0.9743f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8341f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9608f, 0.9208f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9394f, 0.9726f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9708f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9952f, 0.9976f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9922f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, 0.9938f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9911f, 0.9973f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9965f, 0.9966f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9755f, 0.9884f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9602f, 0.9833f, 0.9163f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9950f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9942f, 0.9930f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.9974f, 0.9964f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.9735f, 0.9670f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9802f, 0.9597f, 0.5407f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9887f, 0.8294f, 0.3135f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8949f, 0.7356f, 0.5347f, + 1.0000f, 0.9990f, 0.9940f, 0.9336f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4200f, 1.0000f, 1.0000f, + 1.0000f, 0.9971f, 0.9713f, 0.9954f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8600f, 1.0000f, 1.0000f, + 1.0000f, 0.6754f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9408f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8970f, 0.9513f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 1.0000f, 1.0000f, + 1.0000f, 0.8939f, 0.9986f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9999f, 0.9993f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9997f, 0.9751f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9889f, 0.9992f, 0.9962f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9699f, 0.9997f, 0.8310f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9878f, 0.7462f, 0.5521f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9830f, 0.8019f, 0.8214f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6455f, 0.4052f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4271f, 0.9809f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 0.9999f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 1.0000f, 0.9924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9401f, 0.5733f, 0.9314f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8907f, 0.7566f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3488f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7820f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_5x12[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8780f, 0.9349f, 1.0000f, 1.0000f, 0.9364f, 0.9901f, + 1.0000f, 1.0000f, 1.0000f, 0.9975f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9180f, 0.9637f, 0.9656f, 1.0000f, 1.0000f, 0.9733f, 0.9894f, + 1.0000f, 1.0000f, 0.9802f, 0.9969f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9172f, 0.8662f, 0.5213f, 1.0000f, 1.0000f, 0.9146f, 0.8459f, + 1.0000f, 1.0000f, 0.9914f, 0.9959f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8116f, 0.8244f, 0.4387f, 1.0000f, 0.9313f, 0.9320f, 0.8625f, + 1.0000f, 1.0000f, 0.9589f, 0.9742f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8289f, 0.4504f, 0.4006f, 1.0000f, 0.9104f, 0.8562f, 0.3463f, + 1.0000f, 0.9494f, 0.9864f, 0.9861f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7709f, 0.0893f, 0.6998f, 1.0000f, 0.8274f, 0.7886f, 0.3091f, + 1.0000f, 1.0000f, 0.9069f, 0.9188f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5676f, 0.1455f, 1.0000f, 1.0000f, 0.8362f, 0.5805f, 0.2600f, + 1.0000f, 0.8846f, 0.8197f, 0.5586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4675f, 0.6560f, 1.0000f, 1.0000f, 0.8099f, 0.4897f, 0.7086f, + 1.0000f, 1.0000f, 1.0000f, 0.9506f, 0.5058f, 1.0000f, 1.0000f, 1.0000f, 0.6937f, 1.0000f, 0.8698f, 0.8304f, 0.5929f, 1.0000f, 0.9540f, 0.9721f, + 1.0000f, 1.0000f, 0.9605f, 0.9616f, 0.6722f, 1.0000f, 1.0000f, 1.0000f, 0.7223f, 0.8835f, 0.8745f, 0.8889f, 0.3242f, 1.0000f, 0.9450f, 0.9642f, + 1.0000f, 1.0000f, 0.9391f, 0.9568f, 0.7142f, 1.0000f, 1.0000f, 1.0000f, 0.3317f, 0.8523f, 0.7828f, 0.4842f, 0.7446f, 1.0000f, 0.8549f, 0.8587f, + 1.0000f, 0.9557f, 0.9268f, 0.8710f, 0.6050f, 1.0000f, 1.0000f, 1.0000f, 0.1696f, 0.7997f, 0.4265f, 0.4326f, 1.0000f, 0.8498f, 0.8909f, 0.3167f, + 1.0000f, 1.0000f, 0.8757f, 0.9244f, 0.6816f, 1.0000f, 1.0000f, 1.0000f, 0.6457f, 0.7789f, 0.1325f, 0.5541f, 1.0000f, 0.8939f, 0.6968f, 0.2032f, + 1.0000f, 0.9129f, 0.8066f, 0.6280f, 0.0533f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5312f, 0.1581f, 1.0000f, 1.0000f, 0.7169f, 0.2931f, 0.4787f, + 1.0000f, 0.8929f, 0.8149f, 0.6526f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5450f, 0.3874f, 1.0000f, 1.0000f, 0.7423f, 0.3391f, 0.5763f, + 1.0000f, 0.8333f, 0.7646f, 0.3535f, 0.6422f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2241f, 1.0000f, 1.0000f, 1.0000f, 0.6785f, 0.3807f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8674f, 0.9033f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8347f, 0.7942f, 0.6690f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8734f, 0.5496f, 0.2141f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7749f, 0.3603f, 0.5970f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7375f, 0.0330f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3012f, 0.3739f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9929f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6492f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9923f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0720f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9856f, 0.9963f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7513f, 0.7961f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8376f, 0.8536f, 0.4618f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7468f, 0.2849f, 0.4137f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7114f, 0.1048f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6207f, 0.1186f, 1.0000f, 1.0000f, 1.0000f, 0.9799f, 0.9960f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1811f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 0.9967f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5263f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9573f, 0.9910f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2429f, 1.0000f, 1.0000f, 1.0000f, 0.9562f, 0.9792f, 0.8977f, + 1.0000f, 0.9987f, 0.9976f, 0.9994f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9357f, 0.8445f, 0.9535f, 1.0000f, 0.9769f, 0.9828f, 0.9680f, + 1.0000f, 0.9998f, 1.0000f, 0.9899f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8650f, 0.9438f, 0.9196f, 1.0000f, 0.9237f, 0.9762f, 0.7729f, + 1.0000f, 0.9844f, 0.9892f, 0.9795f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7301f, 0.9398f, 1.0000f, 1.0000f, 0.6244f, 0.8165f, 0.8919f, + 1.0000f, 0.9675f, 0.9853f, 0.8485f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8612f, 1.0000f, 1.0000f, 1.0000f, 0.7847f, 0.8802f, 0.9847f, + 1.0000f, 0.9051f, 0.8722f, 0.9578f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6387f, 0.9024f, 1.0000f, + 1.0000f, 0.8318f, 0.9611f, 0.9600f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8432f, 1.0000f, 1.0000f, + 1.0000f, 0.4446f, 0.8996f, 0.9405f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7351f, 0.9816f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8768f, 0.9431f, 0.7808f, 0.4202f, 1.0000f, 1.0000f, 1.0000f, 0.9703f, 0.7249f, 0.8181f, 0.9716f, 1.0000f, 0.8213f, 0.9260f, 0.9475f, + 1.0000f, 0.9850f, 0.9163f, 0.6626f, 0.6317f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8133f, 0.8987f, 0.9841f, 1.0000f, 0.9750f, 0.8879f, 0.9213f, + 1.0000f, 0.9488f, 0.6877f, 0.7688f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7867f, 1.0000f, 1.0000f, 1.0000f, 0.6130f, 0.9204f, 1.0000f, + 1.0000f, 0.8968f, 0.8418f, 0.8228f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8032f, 0.9512f, 1.0000f, + 1.0000f, 0.4951f, 0.8390f, 0.9651f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6010f, 1.0000f, 1.0000f, + 1.0000f, 0.6658f, 0.9781f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7667f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9155f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5162f, 0.8049f, 0.9694f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6846f, 0.9784f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9988f, 0.9912f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9994f, 0.9005f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.9758f, 0.8259f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9551f, 0.9384f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5888f, 0.8813f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7491f, 0.9729f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9993f, 0.9921f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9991f, 0.9060f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9831f, 0.9925f, 0.9869f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9500f, 0.9777f, 0.8574f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9670f, 0.7979f, 0.8511f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9463f, 0.9661f, 0.9298f, + 1.0000f, 1.0000f, 0.9917f, 0.9996f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9482f, 0.9112f, 0.6352f, 1.0000f, 0.9887f, 0.9523f, 0.9517f, + 1.0000f, 0.9999f, 0.9989f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9078f, 0.7057f, 1.0000f, 1.0000f, 0.9595f, 0.9646f, 0.5110f, + 1.0000f, 0.9984f, 0.9938f, 0.9773f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9121f, 0.9015f, 1.0000f, 1.0000f, 0.9707f, 0.6754f, 0.7196f, + 1.0000f, 0.9940f, 0.9872f, 0.7769f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5005f, 1.0000f, 1.0000f, 1.0000f, 0.8948f, 0.1922f, 1.0000f, + 1.0000f, 0.9858f, 0.8824f, 0.5720f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8899f, 1.0000f, 1.0000f, 1.0000f, 0.9411f, 0.9335f, 1.0000f, + 1.0000f, 0.9229f, 0.7275f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5358f, 1.0000f, 1.0000f, + 1.0000f, 0.9631f, 0.5847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9788f, 1.0000f, 1.0000f, + 1.0000f, 0.8686f, 0.8014f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9890f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9919f, 0.9927f, 0.9546f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9584f, 0.8404f, 0.9689f, 1.0000f, 0.9954f, 0.9095f, 0.6907f, + 1.0000f, 0.9685f, 0.9941f, 0.9290f, 0.9086f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9252f, 0.6168f, 1.0000f, 1.0000f, 0.9283f, 0.8857f, 0.4072f, + 1.0000f, 0.9943f, 0.9806f, 0.9275f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9444f, 1.0000f, 1.0000f, 1.0000f, 0.9469f, 0.2685f, 1.0000f, + 1.0000f, 0.9885f, 0.9666f, 0.9825f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5405f, 1.0000f, 1.0000f, 1.0000f, 0.7580f, 1.0000f, 1.0000f, + 1.0000f, 0.9946f, 0.8791f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8637f, 1.0000f, 1.0000f, + 1.0000f, 0.9698f, 0.9903f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5631f, 1.0000f, 1.0000f, + 1.0000f, 0.9834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8600f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9738f, 0.7923f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9221f, 0.9371f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9378f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9754f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.9955f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 0.9949f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9972f, 0.9933f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9867f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9725f, 0.9877f, 0.9305f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9342f, 0.8082f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9418f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9962f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9951f, 0.9952f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9819f, 0.9626f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9882f, 0.9529f, 0.4562f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.8958f, 0.3672f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9042f, 0.7535f, 0.6090f, + 1.0000f, 0.9993f, 0.9897f, 0.9621f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2515f, 1.0000f, 1.0000f, + 1.0000f, 0.9978f, 0.9837f, 0.9970f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7602f, 1.0000f, 1.0000f, + 1.0000f, 0.7905f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9138f, 0.9457f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9934f, 1.0000f, 1.0000f, + 1.0000f, 0.9327f, 0.9987f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9992f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 1.0000f, 0.9822f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9956f, 0.9985f, 0.9874f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9880f, 0.9998f, 0.8472f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9908f, 0.7326f, 0.4731f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9425f, 0.7399f, 0.7624f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7027f, 0.2767f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3941f, 0.9812f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, 1.0000f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9931f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9809f, 0.6593f, 0.9766f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9746f, 0.8868f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2341f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7558f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_6x4[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9673f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8992f, 0.9737f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9398f, 0.9849f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7787f, 0.8814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8128f, 0.8718f, 0.9182f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9354f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9262f, 0.9793f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8501f, 0.9493f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8559f, 0.8693f, 0.8377f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7200f, 0.7741f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7542f, 0.6070f, 0.3882f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6630f, 0.8167f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6893f, 0.8641f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7078f, 0.6828f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7595f, 0.7647f, 0.6763f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2717f, 0.4628f, 0.0876f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4109f, 0.2335f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9467f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9664f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9823f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8743f, 0.9454f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9054f, 0.9628f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9904f, 0.9993f, 0.9982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9974f, 0.9998f, 0.9817f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9787f, 0.9897f, 0.9834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9530f, 0.9767f, 0.8767f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8205f, 0.7318f, 0.8008f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7259f, 0.8048f, 0.8471f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9967f, 0.9893f, 0.9427f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9959f, 0.9828f, 0.9619f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9231f, 0.7139f, 0.8242f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8883f, 0.9294f, 0.8277f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3079f, 0.5404f, 0.8311f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3622f, 0.8614f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9073f, 0.9384f, 0.8949f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8928f, 0.9148f, 0.5980f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4291f, 0.5542f, 0.8837f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 1.0000f, + 1.0000f, 0.5667f, 0.7434f, 0.8905f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9998f, + 1.0000f, 0.1611f, 0.4950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9656f, 0.9844f, 0.9934f, + 1.0000f, 0.3359f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9811f, 0.9920f, 0.9165f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9987f, 0.9908f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9988f, 0.9564f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9698f, 0.9799f, 0.9598f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9553f, 0.9638f, 0.7878f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9881f, 0.9928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9948f, 0.9980f, 0.9950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9876f, 0.9413f, 0.8860f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9752f, 0.9130f, 0.5107f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9690f, 0.8530f, 0.5777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9441f, 0.6160f, 0.9985f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9858f, 0.9714f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9730f, 0.9868f, 0.9247f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9781f, 0.8089f, 0.4789f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9092f, 0.6244f, 0.5880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9745f, 0.6409f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8587f, 0.9215f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9722f, 0.9647f, 0.8790f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9805f, 0.9198f, 0.7377f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9681f, 0.6955f, 0.9608f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9979f, + 1.0000f, 0.9309f, 0.6327f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9977f, + 1.0000f, 0.9481f, 0.9961f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9706f, 0.9911f, + 1.0000f, 0.6560f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9926f, 0.9923f, 0.9946f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9914f, 0.9901f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9885f, 0.9863f, 0.9760f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9872f, 0.9774f, 0.9505f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9889f, 0.9576f, 0.7488f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9917f, 0.9013f, 0.6696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9854f, 0.8971f, 0.8668f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4462f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7695f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8345f, 0.7965f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6489f, 0.9983f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8440f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9999f, + 1.0000f, 0.9541f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9999f, 0.9971f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9994f, 0.9976f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9931f, 0.9998f, 0.9518f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 0.9369f, 0.7921f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9839f, 0.9278f, 0.9325f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9990f, 0.9941f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, 0.9999f, 0.9587f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9033f, 0.5262f, 0.9340f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8409f, 0.7016f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7833f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9111f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_6x5[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9817f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9250f, 0.9803f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9595f, 0.9914f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8438f, 0.9238f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8903f, 0.9454f, 0.9562f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7381f, 0.8169f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7219f, 0.6800f, 0.5402f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9620f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9587f, 0.9847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9045f, 0.9696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9090f, 0.9325f, 0.8704f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7951f, 0.7921f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7766f, 0.6848f, 0.4307f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8008f, 0.6425f, 0.3692f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6596f, 0.5073f, 0.0799f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6702f, 0.8143f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7040f, 0.8816f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7600f, 0.7419f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7980f, 0.8246f, 0.7891f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7633f, 0.6896f, 0.3081f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6364f, 0.6026f, 0.2805f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9866f, + 1.0000f, 0.2115f, 0.1301f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8951f, + 1.0000f, 0.4014f, 0.1727f, 0.2470f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9420f, 0.9300f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9825f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9881f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9263f, 0.9812f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9628f, 0.9891f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8524f, 0.9186f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8798f, 0.8626f, 0.8545f, + 1.0000f, 0.9939f, 0.9989f, 0.9978f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9993f, 0.9996f, 0.9755f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9799f, 0.9922f, 0.9908f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9604f, 0.9838f, 0.8919f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8415f, 0.8344f, 0.9288f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7531f, 0.9225f, 0.8834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4445f, 0.6235f, 0.8886f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5191f, 0.8967f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9979f, 0.9874f, 0.9349f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9959f, 0.9834f, 0.9675f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9544f, 0.7494f, 0.8586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9408f, 0.9535f, 0.8645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4167f, 0.7456f, 0.8320f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5864f, 0.9465f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3509f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6167f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8935f, 0.9199f, 0.8742f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8665f, 0.9029f, 0.5948f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5687f, 0.6301f, 0.9431f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 1.0000f, + 1.0000f, 0.6484f, 0.8195f, 0.9385f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9997f, + 1.0000f, 0.3314f, 0.7733f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9996f, 0.9991f, + 1.0000f, 0.6098f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9998f, 0.9842f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9570f, 0.9775f, 0.9312f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9862f, 0.9780f, 0.8852f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9993f, 0.9925f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9991f, 0.9487f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9765f, 0.9895f, 0.9808f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9507f, 0.9760f, 0.8565f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9517f, 0.7342f, 0.7700f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9337f, 0.9133f, 0.7799f, + 1.0000f, 1.0000f, 0.9851f, 0.9977f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9980f, 0.9956f, 0.9962f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9870f, 0.9644f, 0.9212f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9722f, 0.9396f, 0.5301f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9579f, 0.7566f, 0.3857f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8779f, 0.4950f, 0.9957f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9683f, 0.7175f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8761f, 0.9014f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9885f, 0.9794f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9750f, 0.9932f, 0.9443f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9830f, 0.8606f, 0.5777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9373f, 0.7302f, 0.6752f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9612f, 0.4702f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7861f, 0.7667f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9690f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8296f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9667f, 0.9716f, 0.8684f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9739f, 0.9361f, 0.6992f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9785f, 0.8035f, 0.9821f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9990f, + 1.0000f, 0.9636f, 0.7260f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9986f, + 1.0000f, 0.9553f, 0.9930f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9904f, 0.9954f, + 1.0000f, 0.6650f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9948f, 0.9982f, + 1.0000f, 0.8998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9790f, 0.9770f, + 1.0000f, 0.9952f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9703f, 0.9911f, 0.9660f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, 0.9981f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9950f, 0.9972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9917f, 0.9935f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9888f, 0.9898f, 0.9859f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9901f, 0.9710f, 0.9119f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9733f, 0.9476f, 0.5594f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9728f, 0.9104f, 0.7830f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9652f, 0.8461f, 0.8116f, + 1.0000f, 0.9944f, 0.9275f, 0.7131f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9937f, 0.9173f, 0.9147f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4827f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8221f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8368f, 0.8392f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7086f, 0.9984f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8503f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9999f, 0.9999f, + 1.0000f, 0.9744f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, 0.9946f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 0.9997f, 0.9976f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9941f, 0.9999f, 0.9526f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9920f, 0.8723f, 0.6944f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9855f, 0.8482f, 0.9160f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9060f, 0.8869f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8271f, 0.9965f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9927f, 0.9985f, 0.9992f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9877f, 0.9998f, 0.9497f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9075f, 0.4576f, 0.8983f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8063f, 0.6541f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5499f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8090f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_6x6[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8106f, 0.8853f, + 1.0000f, 1.0000f, 1.0000f, 0.9930f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7864f, 0.9450f, + 1.0000f, 1.0000f, 0.9513f, 0.9905f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8216f, 0.8013f, + 1.0000f, 1.0000f, 0.9714f, 0.9946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8453f, 0.8645f, 0.8629f, + 1.0000f, 1.0000f, 0.8899f, 0.9579f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8525f, 0.7728f, 0.4573f, + 1.0000f, 0.9120f, 0.9600f, 0.9709f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7079f, 0.7007f, 0.2804f, + 1.0000f, 1.0000f, 0.8434f, 0.8542f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7615f, 0.3425f, 0.0000f, + 1.0000f, 0.8340f, 0.7439f, 0.5516f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6893f, 0.2428f, 0.2979f, + 1.0000f, 1.0000f, 1.0000f, 0.9744f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9764f, 0.9869f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9177f, 0.9724f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9199f, 0.9401f, 0.8679f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8379f, 0.8560f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8279f, 0.7219f, 0.5251f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8471f, 0.7185f, 0.4349f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6933f, 0.5759f, 0.2166f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.6970f, 0.8397f, 0.0794f, 1.0000f, 1.0000f, 1.0000f, 0.0403f, 1.0000f, 1.0000f, 1.0000f, 0.3571f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8320f, 0.9095f, 0.1892f, 1.0000f, 1.0000f, 1.0000f, 0.1171f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7916f, 0.7837f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8259f, 0.8489f, 0.8083f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7965f, 0.7528f, 0.4100f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6853f, 0.6812f, 0.3279f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9897f, + 1.0000f, 0.7252f, 0.3130f, 0.1542f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9807f, + 1.0000f, 0.6646f, 0.2621f, 0.3846f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9833f, 0.9944f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9903f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9908f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9458f, 0.9895f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9719f, 0.9889f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9252f, 0.9749f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9357f, 0.9375f, 0.8957f, + 1.0000f, 0.9957f, 0.9997f, 0.9982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9607f, 0.9729f, 0.9155f, + 1.0000f, 0.9989f, 0.9999f, 0.9794f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9409f, 0.9572f, 0.6555f, + 1.0000f, 0.9773f, 0.9910f, 0.9844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6508f, 0.6154f, 0.9056f, + 1.0000f, 0.9466f, 0.9803f, 0.8823f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7114f, 0.8151f, 0.9434f, + 1.0000f, 0.8869f, 0.8760f, 0.9392f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3710f, 0.9015f, 1.0000f, + 1.0000f, 0.7941f, 0.9426f, 0.9082f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6312f, 1.0000f, 1.0000f, + 1.0000f, 0.5069f, 0.8129f, 0.8928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6411f, 0.9586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9978f, 0.9913f, 0.9302f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9988f, 0.9826f, 0.9482f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9543f, 0.7284f, 0.8695f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9242f, 0.9339f, 0.8986f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4975f, 0.8360f, 0.8884f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6460f, 0.9647f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5680f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6601f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9132f, 0.9166f, 0.8416f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8728f, 0.9029f, 0.5837f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5908f, 0.6261f, 0.9292f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 1.0000f, + 1.0000f, 0.6362f, 0.8195f, 0.9282f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9999f, + 1.0000f, 0.4781f, 0.9043f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9995f, 0.9986f, + 1.0000f, 0.7043f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9999f, 0.9786f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9940f, 0.9593f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9887f, 0.9687f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9996f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9981f, 0.9841f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9974f, 0.9188f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9777f, 0.9915f, 0.9881f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9474f, 0.9830f, 0.8943f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9621f, 0.7700f, 0.8711f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9330f, 0.9550f, 0.8838f, + 1.0000f, 1.0000f, 0.9925f, 0.9987f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9818f, 0.9790f, 0.9703f, + 1.0000f, 0.9969f, 0.9984f, 0.9996f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9854f, 0.9698f, 0.8662f, + 1.0000f, 0.9942f, 0.9628f, 0.9143f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9768f, 0.8776f, 0.9754f, + 1.0000f, 0.9739f, 0.9498f, 0.5161f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9505f, 0.7408f, 1.0000f, + 1.0000f, 0.9653f, 0.8037f, 0.4225f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9348f, 0.9918f, 1.0000f, + 1.0000f, 0.8507f, 0.5341f, 0.9892f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7469f, 1.0000f, 1.0000f, + 1.0000f, 0.9520f, 0.4880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9490f, 1.0000f, 1.0000f, + 1.0000f, 0.8173f, 0.7557f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9875f, 0.9867f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9682f, 0.9952f, 0.9614f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9848f, 0.8791f, 0.6099f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9321f, 0.7499f, 0.7315f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9418f, 0.5430f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8238f, 0.7586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9535f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6208f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9692f, 0.9798f, 0.8913f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9811f, 0.9383f, 0.7378f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, + 1.0000f, 0.9670f, 0.8300f, 0.9822f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9980f, + 1.0000f, 0.9665f, 0.7347f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9955f, + 1.0000f, 0.9565f, 0.9934f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9815f, 0.9947f, + 1.0000f, 0.7149f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.9961f, 0.9976f, + 1.0000f, 0.9659f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9863f, 0.9938f, + 1.0000f, 0.9951f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9759f, 0.9977f, 0.9640f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9900f, 0.9954f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9927f, 0.9958f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9857f, 0.9782f, 0.9837f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9920f, 0.9557f, 0.9272f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9734f, 0.9231f, 0.5598f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9851f, 0.8612f, 0.6039f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9262f, 0.7755f, 0.6689f, + 1.0000f, 0.9949f, 0.9311f, 0.7890f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8578f, 1.0000f, 1.0000f, + 1.0000f, 0.9960f, 0.9366f, 0.9442f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9634f, 1.0000f, 1.0000f, + 1.0000f, 0.4464f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7671f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9001f, 0.9107f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7783f, 0.9998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8744f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9990f, 0.9997f, + 1.0000f, 0.9676f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9932f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9860f, 0.9994f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9872f, 1.0000f, 0.9210f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 0.9069f, 0.6771f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9884f, 0.8972f, 0.9221f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8060f, 0.7989f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6730f, 0.9988f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9878f, 0.9992f, 0.9985f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9923f, 0.9998f, 0.9528f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8807f, 0.3973f, 0.8595f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7643f, 0.5978f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4681f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7811f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_6x8[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7507f, 0.8312f, 1.0000f, 1.0000f, 0.9510f, 0.9872f, + 1.0000f, 1.0000f, 1.0000f, 0.9960f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7791f, 0.8374f, 0.8893f, 1.0000f, 1.0000f, 0.9809f, 0.9948f, + 1.0000f, 1.0000f, 0.9710f, 0.9957f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8389f, 0.7750f, 0.5758f, 1.0000f, 1.0000f, 0.8996f, 0.8296f, + 1.0000f, 1.0000f, 0.9880f, 0.9956f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7361f, 0.7599f, 0.3527f, 1.0000f, 0.9236f, 0.9323f, 0.8634f, + 1.0000f, 1.0000f, 0.9331f, 0.9540f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7483f, 0.4613f, 0.2516f, 1.0000f, 0.9254f, 0.8264f, 0.4148f, + 1.0000f, 0.9441f, 0.9799f, 0.9751f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7013f, 0.1466f, 0.7850f, 1.0000f, 0.7870f, 0.7459f, 0.3889f, + 1.0000f, 1.0000f, 0.8858f, 0.8905f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6250f, 0.0671f, 1.0000f, 1.0000f, 0.8434f, 0.4063f, 0.1118f, + 1.0000f, 0.8578f, 0.7947f, 0.5703f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3140f, 0.4470f, 1.0000f, 1.0000f, 0.7261f, 0.2774f, 0.4683f, + 1.0000f, 1.0000f, 1.0000f, 0.9918f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9600f, 0.9795f, + 1.0000f, 1.0000f, 0.9890f, 0.9950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9306f, 0.9573f, + 1.0000f, 1.0000f, 0.9551f, 0.9818f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8216f, 0.8535f, + 1.0000f, 0.9516f, 0.9534f, 0.9040f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8620f, 0.9083f, 0.4231f, + 1.0000f, 1.0000f, 0.8962f, 0.9007f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9157f, 0.6601f, 0.1800f, + 1.0000f, 0.8916f, 0.7966f, 0.5647f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6677f, 0.3618f, 0.3343f, + 1.0000f, 0.9167f, 0.7927f, 0.5342f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7386f, 0.1634f, 0.3020f, + 1.0000f, 0.7687f, 0.6559f, 0.2897f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5591f, 0.1293f, 1.0000f, + 1.0000f, 1.0000f, 0.7435f, 0.8798f, 0.6474f, 1.0000f, 1.0000f, 1.0000f, 0.1950f, 1.0000f, 1.0000f, 1.0000f, 0.5959f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9051f, 0.9314f, 0.5085f, 1.0000f, 1.0000f, 1.0000f, 0.2645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8507f, 0.8248f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8881f, 0.8973f, 0.8419f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8564f, 0.8059f, 0.5150f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7411f, 0.7729f, 0.4394f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, + 1.0000f, 0.7984f, 0.5279f, 0.2378f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9862f, + 1.0000f, 0.7531f, 0.4313f, 0.5909f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9864f, 0.9927f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9947f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9646f, 0.9920f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9827f, 0.9940f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9461f, 0.9839f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9474f, 0.9568f, 0.8674f, + 1.0000f, 0.9972f, 0.9996f, 0.9991f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8700f, 0.7129f, 0.7156f, 1.0000f, 0.9915f, 0.9922f, 0.9770f, + 1.0000f, 0.9998f, 0.9999f, 0.9815f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7708f, 0.7337f, 0.7771f, 1.0000f, 0.9651f, 0.9902f, 0.8449f, + 1.0000f, 0.9792f, 0.9931f, 0.9885f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4819f, 0.9546f, 1.0000f, 1.0000f, 0.6639f, 0.8232f, 0.9697f, + 1.0000f, 0.9454f, 0.9774f, 0.9093f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7043f, 1.0000f, 1.0000f, 1.0000f, 0.8022f, 0.9115f, 0.9631f, + 1.0000f, 0.8822f, 0.8761f, 0.9378f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6340f, 0.9207f, 1.0000f, + 1.0000f, 0.8095f, 0.9562f, 0.9197f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8182f, 1.0000f, 1.0000f, + 1.0000f, 0.5019f, 0.9029f, 0.9281f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7209f, 0.9777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9995f, 0.9925f, 0.9467f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8687f, 0.9347f, 0.9289f, + 1.0000f, 0.9990f, 0.9851f, 0.9589f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9719f, 0.8869f, 0.8846f, + 1.0000f, 0.9675f, 0.7889f, 0.9072f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6058f, 0.8521f, 1.0000f, + 1.0000f, 0.9413f, 0.9492f, 0.9339f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7182f, 0.9400f, 1.0000f, + 1.0000f, 0.4953f, 0.9136f, 0.9272f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6714f, 1.0000f, 1.0000f, + 1.0000f, 0.7101f, 0.9802f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6918f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7665f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9245f, 0.9187f, 0.8492f, 0.5531f, 1.0000f, 1.0000f, 1.0000f, 0.0934f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8606f, 0.8951f, 0.5215f, 0.2100f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6295f, 0.6886f, 0.9522f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, + 1.0000f, 0.6750f, 0.8550f, 0.9528f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9996f, + 1.0000f, 0.6009f, 0.9498f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.9995f, 0.9980f, + 1.0000f, 0.8148f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 1.0000f, 0.9504f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9911f, 0.9298f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9875f, 0.9731f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9987f, 0.9788f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9971f, 0.8984f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9684f, 0.9898f, 0.9833f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9363f, 0.9743f, 0.8358f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9665f, 0.7643f, 0.8737f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9370f, 0.9610f, 0.8786f, + 1.0000f, 1.0000f, 0.9942f, 0.9964f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9693f, 0.9661f, 0.8592f, 1.0000f, 0.9913f, 0.9755f, 0.9688f, + 1.0000f, 0.9988f, 0.9970f, 0.9993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9723f, 0.9177f, 1.0000f, 1.0000f, 0.9883f, 0.9762f, 0.6982f, + 1.0000f, 0.9938f, 0.9888f, 0.9595f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9605f, 0.9895f, 1.0000f, 1.0000f, 0.9486f, 0.7235f, 0.8774f, + 1.0000f, 0.9867f, 0.9679f, 0.5809f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8464f, 1.0000f, 1.0000f, 1.0000f, 0.9146f, 0.3977f, 1.0000f, + 1.0000f, 0.9739f, 0.8404f, 0.3800f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9727f, 1.0000f, 1.0000f, 1.0000f, 0.8648f, 0.9226f, 1.0000f, + 1.0000f, 0.8939f, 0.5469f, 0.9983f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4542f, 1.0000f, 1.0000f, + 1.0000f, 0.9480f, 0.3251f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9217f, 1.0000f, 1.0000f, + 1.0000f, 0.7621f, 0.6518f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9621f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9935f, 0.9936f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9836f, 0.9848f, 0.7831f, + 1.0000f, 0.9878f, 0.9959f, 0.9714f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9702f, 0.9406f, 0.7811f, + 1.0000f, 0.9953f, 0.9385f, 0.7312f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9579f, 0.6430f, 1.0000f, + 1.0000f, 0.9641f, 0.8749f, 0.8810f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8478f, 1.0000f, 1.0000f, + 1.0000f, 0.9584f, 0.6385f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9061f, 1.0000f, 1.0000f, + 1.0000f, 0.8280f, 0.8199f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6950f, 1.0000f, 1.0000f, + 1.0000f, 0.9434f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6155f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9806f, 0.9766f, 0.9104f, 0.0354f, 1.0000f, 1.0000f, 1.0000f, 0.4752f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9900f, 0.9427f, 0.7577f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, + 1.0000f, 0.9785f, 0.9125f, 0.9977f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9994f, + 1.0000f, 0.9812f, 0.8077f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9929f, + 1.0000f, 0.9616f, 0.9968f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 0.9905f, + 1.0000f, 0.7908f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, 0.9954f, 0.9984f, + 1.0000f, 0.9557f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9821f, 0.9909f, + 1.0000f, 0.9853f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9830f, 0.9924f, 0.9636f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9978f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9973f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9706f, 0.9981f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.9945f, 0.9933f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9392f, 0.9263f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9670f, 0.9355f, 0.3709f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9907f, 0.8165f, 0.4886f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8724f, 0.7287f, 0.5860f, + 1.0000f, 0.9992f, 0.9759f, 0.8661f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6819f, 1.0000f, 1.0000f, + 1.0000f, 0.9986f, 0.9747f, 0.9842f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9447f, 1.0000f, 1.0000f, + 1.0000f, 0.5406f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9420f, 0.9656f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 1.0000f, 1.0000f, + 1.0000f, 0.9018f, 0.9996f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9999f, 0.9999f, + 1.0000f, 0.9626f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9781f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9824f, 0.9994f, 0.9969f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9856f, 0.9998f, 0.8928f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9859f, 0.8003f, 0.6107f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9845f, 0.8113f, 0.8131f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8041f, 0.7073f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6785f, 0.9989f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9893f, 1.0000f, 0.9987f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9870f, 1.0000f, 0.9735f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8327f, 0.3436f, 0.8343f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7554f, 0.6203f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2239f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6852f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_6x10[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9113f, 0.9605f, 1.0000f, 1.0000f, 0.9651f, 0.9905f, + 1.0000f, 1.0000f, 1.0000f, 0.9986f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9297f, 0.9572f, 0.9655f, 1.0000f, 1.0000f, 0.9680f, 0.9938f, + 1.0000f, 1.0000f, 0.9769f, 0.9966f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9434f, 0.8648f, 0.4724f, 1.0000f, 1.0000f, 0.9029f, 0.8206f, + 1.0000f, 1.0000f, 0.9929f, 0.9937f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8133f, 0.7768f, 0.4066f, 1.0000f, 0.9338f, 0.9224f, 0.8220f, + 1.0000f, 1.0000f, 0.9384f, 0.9696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8118f, 0.4443f, 0.3663f, 1.0000f, 0.9358f, 0.8449f, 0.3799f, + 1.0000f, 0.9624f, 0.9881f, 0.9847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7514f, 0.0924f, 0.7271f, 1.0000f, 0.8057f, 0.7892f, 0.3453f, + 1.0000f, 1.0000f, 0.8889f, 0.8976f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7575f, 0.0336f, 1.0000f, 1.0000f, 0.8849f, 0.4385f, 0.1879f, + 1.0000f, 0.8909f, 0.8072f, 0.5233f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3074f, 0.3933f, 1.0000f, 1.0000f, 0.7857f, 0.2391f, 0.5425f, + 1.0000f, 1.0000f, 1.0000f, 0.9927f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8869f, 0.8500f, 1.0000f, 1.0000f, 0.9712f, 0.9720f, + 1.0000f, 1.0000f, 0.9890f, 0.9970f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8985f, 0.9391f, 0.8695f, 1.0000f, 1.0000f, 0.9446f, 0.9736f, + 1.0000f, 1.0000f, 0.9659f, 0.9844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8659f, 0.7674f, 0.4262f, 1.0000f, 1.0000f, 0.8474f, 0.8900f, + 1.0000f, 0.9692f, 0.9783f, 0.9020f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7804f, 0.4000f, 0.3231f, 1.0000f, 0.8838f, 0.9397f, 0.4559f, + 1.0000f, 1.0000f, 0.9246f, 0.9311f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7994f, 0.1379f, 0.6466f, 1.0000f, 0.9208f, 0.7374f, 0.3153f, + 1.0000f, 0.9201f, 0.8397f, 0.6361f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5610f, 0.1510f, 1.0000f, 1.0000f, 0.7219f, 0.3523f, 0.5786f, + 1.0000f, 0.9177f, 0.8423f, 0.5185f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5656f, 0.1641f, 1.0000f, 1.0000f, 0.7875f, 0.2300f, 0.4935f, + 1.0000f, 0.8192f, 0.6885f, 0.2571f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1230f, 1.0000f, 1.0000f, 1.0000f, 0.6501f, 0.2916f, 1.0000f, + 1.0000f, 1.0000f, 0.7712f, 0.9063f, 0.6824f, 1.0000f, 1.0000f, 1.0000f, 0.2659f, 1.0000f, 0.6762f, 0.7749f, 0.7348f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9216f, 0.9193f, 0.6252f, 1.0000f, 1.0000f, 1.0000f, 0.2995f, 0.6215f, 0.7030f, 0.6915f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8550f, 0.8318f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7654f, 0.5869f, 0.2099f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8994f, 0.8752f, 0.8277f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7534f, 0.4778f, 0.5086f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9011f, 0.8624f, 0.5987f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6666f, 0.1080f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7909f, 0.8291f, 0.4987f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4197f, 0.6026f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9932f, + 1.0000f, 0.8088f, 0.5700f, 0.2747f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6289f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, + 1.0000f, 0.7731f, 0.4670f, 0.6855f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0749f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9903f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5948f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9799f, 0.9958f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9886f, 0.9922f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9525f, 0.9790f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9628f, 0.9610f, 0.8487f, + 1.0000f, 0.9992f, 0.9991f, 0.9990f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9254f, 0.8817f, 0.9231f, 1.0000f, 0.9836f, 0.9925f, 0.9776f, + 1.0000f, 0.9997f, 0.9999f, 0.9897f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8636f, 0.9331f, 0.9504f, 1.0000f, 0.9577f, 0.9838f, 0.8148f, + 1.0000f, 0.9821f, 0.9899f, 0.9849f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6730f, 0.9046f, 1.0000f, 1.0000f, 0.6103f, 0.8162f, 0.9096f, + 1.0000f, 0.9428f, 0.9793f, 0.8740f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8512f, 1.0000f, 1.0000f, 1.0000f, 0.7555f, 0.8763f, 0.9684f, + 1.0000f, 0.9283f, 0.8938f, 0.9762f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6601f, 0.9003f, 1.0000f, + 1.0000f, 0.8525f, 0.9747f, 0.9520f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8263f, 1.0000f, 1.0000f, + 1.0000f, 0.4133f, 0.8706f, 0.9276f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7470f, 0.9812f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9985f, 0.9913f, 0.9546f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7323f, 0.7245f, 0.9104f, 1.0000f, 0.8806f, 0.9552f, 0.9664f, + 1.0000f, 0.9997f, 0.9901f, 0.9637f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7786f, 0.8331f, 0.9765f, 1.0000f, 0.9892f, 0.9261f, 0.9557f, + 1.0000f, 0.9705f, 0.7944f, 0.8948f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7693f, 1.0000f, 1.0000f, 1.0000f, 0.7059f, 0.9452f, 1.0000f, + 1.0000f, 0.9458f, 0.9498f, 0.9351f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8671f, 0.9672f, 1.0000f, + 1.0000f, 0.5282f, 0.9304f, 0.9541f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7297f, 1.0000f, 1.0000f, + 1.0000f, 0.7635f, 0.9883f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7492f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8041f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9161f, 0.8929f, 0.8103f, 0.6431f, 1.0000f, 1.0000f, 1.0000f, 0.2832f, 0.5037f, 0.6064f, 0.9728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8575f, 0.8828f, 0.4501f, 0.3732f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5743f, 0.8344f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5829f, 0.6794f, 0.9440f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.6698f, 0.8587f, 0.9581f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9994f, + 1.0000f, 0.6944f, 0.9755f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9989f, 0.9961f, + 1.0000f, 0.8784f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9996f, 0.9365f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9806f, 0.8718f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9724f, 0.9470f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9964f, 0.9709f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9973f, 0.8773f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9802f, 0.9915f, 0.9857f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9324f, 0.9824f, 0.8384f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9481f, 0.7423f, 0.8235f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9185f, 0.9422f, 0.8358f, + 1.0000f, 1.0000f, 0.9935f, 0.9989f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9596f, 0.9290f, 0.7615f, 1.0000f, 0.9918f, 0.9740f, 0.9830f, + 1.0000f, 0.9977f, 0.9995f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9403f, 0.7595f, 1.0000f, 1.0000f, 0.9701f, 0.9633f, 0.6534f, + 1.0000f, 0.9951f, 0.9688f, 0.9591f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9169f, 0.9562f, 1.0000f, 1.0000f, 0.9536f, 0.6634f, 0.7398f, + 1.0000f, 0.9888f, 0.9531f, 0.7113f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7002f, 1.0000f, 1.0000f, 1.0000f, 0.8537f, 0.2204f, 1.0000f, + 1.0000f, 0.9773f, 0.8729f, 0.4325f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8919f, 1.0000f, 1.0000f, 1.0000f, 0.8611f, 0.8410f, 1.0000f, + 1.0000f, 0.9129f, 0.6141f, 0.9975f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3593f, 1.0000f, 1.0000f, + 1.0000f, 0.9410f, 0.3866f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9071f, 1.0000f, 1.0000f, + 1.0000f, 0.7927f, 0.5909f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9088f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9941f, 0.9971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9732f, 0.9145f, 0.9950f, 1.0000f, 0.9969f, 0.9345f, 0.7839f, + 1.0000f, 0.9841f, 0.9974f, 0.9796f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9509f, 0.8010f, 1.0000f, 1.0000f, 0.9493f, 0.9515f, 0.6973f, + 1.0000f, 0.9920f, 0.9378f, 0.8026f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9487f, 1.0000f, 1.0000f, 1.0000f, 0.9646f, 0.4884f, 1.0000f, + 1.0000f, 0.9779f, 0.9153f, 0.8957f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7447f, 1.0000f, 1.0000f, 1.0000f, 0.8249f, 1.0000f, 1.0000f, + 1.0000f, 0.9751f, 0.7140f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8859f, 1.0000f, 1.0000f, + 1.0000f, 0.9080f, 0.9371f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5330f, 1.0000f, 1.0000f, + 1.0000f, 0.9464f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6325f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9943f, 0.9833f, 0.9137f, 0.7166f, 1.0000f, 1.0000f, 1.0000f, 0.6178f, 0.9615f, 0.9317f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9949f, 0.9567f, 0.7821f, 0.0544f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9601f, 0.9867f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9947f, + 1.0000f, 0.9815f, 0.8966f, 0.9981f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9668f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9956f, 0.9994f, + 1.0000f, 0.9786f, 0.8599f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9869f, + 1.0000f, 0.9743f, 0.9982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9874f, + 1.0000f, 0.8462f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9954f, 0.9965f, + 1.0000f, 0.9476f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9879f, 0.9852f, + 1.0000f, 0.9911f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9827f, 0.9980f, 0.9239f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9944f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9959f, 0.9960f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9917f, 0.9967f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, 0.9864f, 0.9934f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 0.9037f, 0.9642f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9758f, 0.9676f, 0.3382f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9895f, 0.8177f, 0.2481f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8371f, 0.6396f, 0.4616f, + 1.0000f, 0.9992f, 0.9931f, 0.9268f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5378f, 1.0000f, 1.0000f, + 1.0000f, 0.9993f, 0.9876f, 0.9983f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8562f, 1.0000f, 1.0000f, + 1.0000f, 0.5518f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9121f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9619f, 0.9716f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9416f, 0.9995f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8879f, 1.0000f, 1.0000f, 0.5472f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9995f, 0.9998f, + 1.0000f, 0.9586f, 1.0000f, 1.0000f, 0.1993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, 0.9809f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9859f, 0.9972f, 0.9940f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9872f, 0.9997f, 0.8795f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.8683f, 0.5565f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9862f, 0.8304f, 0.7977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7192f, 0.4831f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5136f, 0.9909f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9907f, 0.9998f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9818f, 1.0000f, 0.9854f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9054f, 0.3309f, 0.8436f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7961f, 0.6568f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1765f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7086f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_6x12[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9358f, 0.9687f, 1.0000f, 1.0000f, 0.9758f, 0.9938f, + 1.0000f, 1.0000f, 1.0000f, 0.9976f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9388f, 0.9790f, 0.9579f, 1.0000f, 1.0000f, 0.9956f, 0.9959f, + 1.0000f, 1.0000f, 0.9823f, 0.9981f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9393f, 0.8955f, 0.5579f, 1.0000f, 1.0000f, 0.9352f, 0.8171f, + 1.0000f, 1.0000f, 0.9961f, 0.9958f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8496f, 0.8435f, 0.4922f, 1.0000f, 0.9433f, 0.9471f, 0.8360f, + 1.0000f, 1.0000f, 0.9751f, 0.9655f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8472f, 0.5535f, 0.4179f, 1.0000f, 0.9323f, 0.8920f, 0.4065f, + 1.0000f, 0.9817f, 0.9834f, 0.9907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8254f, 0.1082f, 0.7436f, 1.0000f, 0.8460f, 0.7976f, 0.3593f, + 1.0000f, 1.0000f, 0.9410f, 0.9212f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8100f, 0.0675f, 1.0000f, 1.0000f, 0.9170f, 0.5706f, 0.2586f, + 1.0000f, 0.9232f, 0.8531f, 0.6146f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4290f, 0.5024f, 1.0000f, 1.0000f, 0.8588f, 0.3338f, 0.6441f, + 1.0000f, 1.0000f, 1.0000f, 0.9893f, 0.5788f, 1.0000f, 1.0000f, 1.0000f, 0.7577f, 1.0000f, 0.9112f, 0.8718f, 0.6181f, 1.0000f, 0.9829f, 0.9864f, + 1.0000f, 1.0000f, 0.9903f, 0.9939f, 0.7260f, 1.0000f, 1.0000f, 1.0000f, 0.7673f, 0.8972f, 0.9119f, 0.8837f, 0.3715f, 1.0000f, 0.9724f, 0.9663f, + 1.0000f, 1.0000f, 0.9802f, 0.9871f, 0.7457f, 1.0000f, 1.0000f, 1.0000f, 0.3891f, 0.8980f, 0.8185f, 0.5219f, 0.7857f, 1.0000f, 0.8769f, 0.8610f, + 1.0000f, 0.9787f, 0.9854f, 0.9127f, 0.6964f, 1.0000f, 1.0000f, 1.0000f, 0.1538f, 0.8410f, 0.4767f, 0.4973f, 1.0000f, 0.8893f, 0.9225f, 0.2978f, + 1.0000f, 1.0000f, 0.9427f, 0.9279f, 0.7066f, 1.0000f, 1.0000f, 1.0000f, 0.6938f, 0.8565f, 0.1859f, 0.6345f, 1.0000f, 0.9259f, 0.7749f, 0.2331f, + 1.0000f, 0.9539f, 0.8484f, 0.6628f, 0.0953f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6598f, 0.2242f, 1.0000f, 1.0000f, 0.7616f, 0.3196f, 0.5264f, + 1.0000f, 0.9498f, 0.8903f, 0.6280f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6214f, 0.2151f, 1.0000f, 1.0000f, 0.8295f, 0.2420f, 0.4664f, + 1.0000f, 0.8738f, 0.7394f, 0.3531f, 0.6473f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1202f, 1.0000f, 1.0000f, 1.0000f, 0.7236f, 0.3051f, 1.0000f, + 1.0000f, 1.0000f, 0.8085f, 0.9252f, 0.6885f, 1.0000f, 1.0000f, 1.0000f, 0.3469f, 1.0000f, 0.9052f, 0.9205f, 0.7635f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9534f, 0.9518f, 0.7188f, 1.0000f, 1.0000f, 1.0000f, 0.3654f, 0.9029f, 0.8423f, 0.7164f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9455f, 0.8385f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9239f, 0.6312f, 0.2750f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9272f, 0.9370f, 0.8599f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8321f, 0.3833f, 0.6377f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9060f, 0.9134f, 0.5936f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8213f, 0.0524f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8654f, 0.8856f, 0.5074f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4716f, 0.5124f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, + 1.0000f, 0.8334f, 0.7212f, 0.3950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7477f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, + 1.0000f, 0.8938f, 0.5747f, 0.7351f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0193f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.9929f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0371f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8114f, 0.8448f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6112f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8911f, 0.9067f, 0.5356f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8069f, 0.3404f, 0.4819f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7804f, 0.1429f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7116f, 0.1645f, 1.0000f, 1.0000f, 1.0000f, 0.9847f, 0.9932f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2668f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9937f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6042f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9744f, 0.9873f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1961f, 1.0000f, 1.0000f, 1.0000f, 0.9731f, 0.9774f, 0.8676f, + 1.0000f, 0.9978f, 0.9990f, 0.9994f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9422f, 0.8643f, 0.9588f, 1.0000f, 0.9808f, 0.9866f, 0.9646f, + 1.0000f, 0.9998f, 0.9993f, 0.9890f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8749f, 0.9329f, 0.9341f, 1.0000f, 0.9292f, 0.9784f, 0.7875f, + 1.0000f, 0.9842f, 0.9946f, 0.9857f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7415f, 0.9265f, 1.0000f, 1.0000f, 0.5900f, 0.8038f, 0.8865f, + 1.0000f, 0.9524f, 0.9899f, 0.8846f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8818f, 1.0000f, 1.0000f, 1.0000f, 0.7518f, 0.8554f, 0.9826f, + 1.0000f, 0.9097f, 0.8929f, 0.9716f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6990f, 0.9191f, 1.0000f, + 1.0000f, 0.8632f, 0.9690f, 0.9598f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8778f, 1.0000f, 1.0000f, + 1.0000f, 0.4612f, 0.9105f, 0.9616f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7786f, 0.9850f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9989f, 0.9954f, 0.9574f, 0.4506f, 1.0000f, 1.0000f, 1.0000f, 0.9702f, 0.7557f, 0.8268f, 0.9748f, 1.0000f, 0.8398f, 0.9405f, 0.9593f, + 1.0000f, 0.9990f, 0.9919f, 0.9638f, 0.6077f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8241f, 0.9298f, 0.9915f, 1.0000f, 0.9839f, 0.8963f, 0.9364f, + 1.0000f, 0.9771f, 0.8199f, 0.9021f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8054f, 1.0000f, 1.0000f, 1.0000f, 0.5828f, 0.8542f, 1.0000f, + 1.0000f, 0.9529f, 0.9492f, 0.9564f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8023f, 0.9559f, 1.0000f, + 1.0000f, 0.5446f, 0.9198f, 0.9629f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6007f, 1.0000f, 1.0000f, + 1.0000f, 0.7943f, 0.9877f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8144f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9005f, 0.8875f, 0.7840f, 0.7016f, 1.0000f, 1.0000f, 1.0000f, 0.2503f, 0.5664f, 0.8129f, 0.9761f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8808f, 0.8519f, 0.3774f, 0.4870f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7091f, 0.9764f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6567f, 0.6717f, 0.9347f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 1.0000f, + 1.0000f, 0.6858f, 0.8281f, 0.9694f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, + 1.0000f, 0.6775f, 0.9698f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9982f, 0.9934f, + 1.0000f, 0.8687f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9996f, 0.9044f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9768f, 0.8507f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.9667f, 0.9438f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5864f, 0.8827f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7596f, 0.9741f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9970f, 0.9734f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9975f, 0.8697f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9705f, 0.9861f, 0.9793f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9037f, 0.9642f, 0.8227f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9482f, 0.7373f, 0.8373f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9317f, 0.9476f, 0.9184f, + 1.0000f, 1.0000f, 0.9982f, 0.9984f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9611f, 0.9607f, 0.6911f, 1.0000f, 0.9950f, 0.9713f, 0.9569f, + 1.0000f, 0.9994f, 0.9992f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9671f, 0.7538f, 1.0000f, 1.0000f, 0.9875f, 0.9659f, 0.5971f, + 1.0000f, 0.9935f, 0.9852f, 0.9845f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9162f, 0.8728f, 1.0000f, 1.0000f, 0.9926f, 0.6688f, 0.6658f, + 1.0000f, 0.9927f, 0.9796f, 0.7711f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5401f, 1.0000f, 1.0000f, 1.0000f, 0.9013f, 0.1752f, 1.0000f, + 1.0000f, 0.9924f, 0.8788f, 0.5491f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8621f, 1.0000f, 1.0000f, 1.0000f, 0.9246f, 0.7959f, 1.0000f, + 1.0000f, 0.9513f, 0.6746f, 0.9997f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4345f, 1.0000f, 1.0000f, + 1.0000f, 0.9820f, 0.4235f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9382f, 1.0000f, 1.0000f, + 1.0000f, 0.8347f, 0.6536f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9090f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9965f, 0.9991f, 0.9544f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.9620f, 0.8708f, 0.9683f, 1.0000f, 0.9901f, 0.9651f, 0.7909f, + 1.0000f, 0.9971f, 0.9996f, 0.9837f, 0.9075f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9720f, 0.6504f, 1.0000f, 1.0000f, 0.9583f, 0.9285f, 0.5173f, + 1.0000f, 0.9964f, 0.9487f, 0.8576f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9444f, 1.0000f, 1.0000f, 1.0000f, 0.9679f, 0.3124f, 1.0000f, + 1.0000f, 0.9911f, 0.9304f, 0.9082f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5310f, 1.0000f, 1.0000f, 1.0000f, 0.7730f, 1.0000f, 1.0000f, + 1.0000f, 0.9882f, 0.7283f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8798f, 1.0000f, 1.0000f, + 1.0000f, 0.9310f, 0.9148f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2827f, 1.0000f, 1.0000f, + 1.0000f, 0.9781f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7041f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9941f, 0.9917f, 0.8989f, 0.7140f, 1.0000f, 1.0000f, 1.0000f, 0.6831f, 0.9905f, 0.7992f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9968f, 0.9755f, 0.7692f, 0.0818f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9449f, 0.9465f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, + 1.0000f, 0.9895f, 0.8884f, 0.9962f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9460f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9984f, + 1.0000f, 0.9814f, 0.8007f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9508f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9955f, + 1.0000f, 0.9727f, 0.9988f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9859f, 0.9951f, + 1.0000f, 0.7926f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9923f, 0.9993f, + 1.0000f, 0.9376f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9921f, 0.9738f, + 1.0000f, 0.9884f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9811f, 0.9831f, 0.9399f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9634f, 0.8308f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9549f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.9966f, 0.9868f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 0.9709f, 0.9155f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 0.9177f, 0.3267f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9931f, 0.8946f, 0.2903f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9335f, 0.6803f, 0.4399f, + 1.0000f, 0.9995f, 0.9945f, 0.9554f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4122f, 1.0000f, 1.0000f, + 1.0000f, 0.9997f, 0.9880f, 0.9942f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7654f, 1.0000f, 1.0000f, + 1.0000f, 0.7498f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9602f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9805f, 0.9897f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 1.0000f, 1.0000f, + 1.0000f, 0.9141f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8158f, 1.0000f, 1.0000f, 0.6409f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, + 1.0000f, 0.9503f, 1.0000f, 1.0000f, 0.2058f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 1.0000f, 0.9777f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9913f, 0.9995f, 0.9909f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9625f, 0.9996f, 0.8665f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.7892f, 0.4559f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9675f, 0.7767f, 0.7306f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7329f, 0.4008f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4453f, 0.9799f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9886f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 1.0000f, 0.9888f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9416f, 0.5622f, 0.9219f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8997f, 0.7822f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1318f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6247f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_8x4[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5963f, 0.7486f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9848f, 1.0000f, 0.6398f, 0.7224f, 0.8643f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9457f, 0.9860f, 1.0000f, 0.7062f, 0.6776f, 0.3793f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9709f, 0.9926f, 1.0000f, 0.6455f, 0.6093f, 0.2651f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8467f, 0.9265f, 1.0000f, 0.1066f, 0.2089f, 0.1762f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9062f, 0.9314f, 0.9622f, 1.0000f, 0.3263f, 0.0000f, 0.4242f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9684f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9578f, 0.9940f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9175f, 0.9677f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9161f, 0.9372f, 0.8867f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8299f, 0.8797f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8323f, 0.7413f, 0.5665f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8917f, 0.9715f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9495f, 0.9852f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8491f, 0.8088f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8622f, 0.8900f, 0.8197f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8683f, 0.7659f, 0.3625f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7522f, 0.6725f, 0.2412f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9703f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9016f, 0.9426f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8779f, 0.9447f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7592f, 0.7852f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9885f, + 1.0000f, 0.7820f, 0.8558f, 0.3060f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9909f, + 1.0000f, 0.8396f, 0.4941f, 0.0653f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9436f, 0.9738f, + 1.0000f, 0.5503f, 0.2856f, 0.1425f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9513f, 0.9798f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9968f, 0.9992f, 0.9977f, 1.0000f, 0.7945f, 0.6278f, 0.7185f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9990f, 0.9998f, 0.9636f, 1.0000f, 0.6672f, 0.7339f, 0.7692f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9794f, 0.9918f, 0.9871f, 1.0000f, 0.4107f, 0.8884f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9505f, 0.9749f, 0.8741f, 1.0000f, 0.6512f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8951f, 0.7975f, 0.8833f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8116f, 0.8815f, 0.9119f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9978f, 0.9907f, 0.9228f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9995f, 0.9844f, 0.9696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9600f, 0.7883f, 0.8850f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9383f, 0.9563f, 0.8444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4499f, 0.6826f, 0.9032f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5238f, 0.9290f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9808f, 0.9875f, 0.9690f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9585f, 0.9726f, 0.8372f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5745f, 0.7757f, 0.9615f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 1.0000f, + 1.0000f, 0.7264f, 0.8984f, 0.9349f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, + 1.0000f, 0.3446f, 0.8580f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9826f, 0.9901f, 0.9949f, + 1.0000f, 0.6566f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9912f, 0.9953f, 0.9147f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8143f, 0.8663f, 0.9105f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 1.0000f, + 1.0000f, 0.9486f, 0.8033f, 0.8420f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9987f, + 1.0000f, 0.4726f, 0.8536f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9994f, 0.9923f, + 1.0000f, 0.6338f, 0.8934f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9991f, 0.9467f, + 1.0000f, 0.5047f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9835f, 0.9856f, 0.9629f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9607f, 0.9743f, 0.7914f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9789f, 0.9895f, 1.0000f, 0.9253f, 0.8601f, 0.8004f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9976f, 0.9888f, 0.9955f, 1.0000f, 0.9522f, 0.7557f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9904f, 0.9530f, 0.9188f, 1.0000f, 0.9547f, 0.9938f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9759f, 0.9302f, 0.4614f, 1.0000f, 0.7104f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9764f, 0.9091f, 0.6875f, 1.0000f, 0.9000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9593f, 0.7301f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9754f, 0.9812f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9784f, 0.9817f, 0.9405f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9769f, 0.8170f, 0.4834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8967f, 0.6972f, 0.5585f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9822f, 0.6924f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9077f, 0.9215f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9830f, 0.9643f, 0.9278f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9664f, 0.9415f, 0.6156f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, + 1.0000f, 0.9539f, 0.6030f, 0.8249f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9983f, + 1.0000f, 0.8703f, 0.3956f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9993f, + 1.0000f, 0.9555f, 0.9928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9732f, 0.9898f, + 1.0000f, 0.7018f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9951f, 0.9966f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9779f, 0.9337f, 0.7145f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9959f, 0.9974f, + 1.0000f, 0.9671f, 0.8760f, 0.6619f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9965f, + 1.0000f, 0.9477f, 0.5146f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9982f, + 1.0000f, 0.8061f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9931f, 0.9920f, 0.9915f, + 1.0000f, 0.9570f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.9891f, 0.9657f, + 1.0000f, 0.9360f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9947f, 0.9774f, 0.8274f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9867f, 0.8223f, 0.5420f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9803f, 0.7789f, 0.7626f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4376f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7376f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7725f, 0.6217f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5894f, 0.9936f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5821f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9996f, 0.9994f, + 1.0000f, 0.9047f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9933f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9997f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9997f, 0.9721f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, 0.9394f, 0.8348f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9863f, 0.9326f, 0.9241f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9989f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9882f, 0.9990f, 0.9961f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9878f, 0.9999f, 0.9202f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9133f, 0.5329f, 0.9650f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8514f, 0.7450f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8722f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9839f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_8x5[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6120f, 0.7696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9884f, 1.0000f, 0.6510f, 0.7169f, 0.8592f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9559f, 0.9917f, 1.0000f, 0.7477f, 0.7506f, 0.4645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9756f, 0.9915f, 1.0000f, 0.6919f, 0.7135f, 0.4257f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8997f, 0.9452f, 1.0000f, 0.6803f, 0.3829f, 0.3319f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9256f, 0.9644f, 0.9682f, 1.0000f, 0.6067f, 0.1057f, 0.6598f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.7850f, 0.9046f, 1.0000f, 0.0406f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8524f, 0.7722f, 0.6420f, 1.0000f, 0.1579f, 0.2461f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9765f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9751f, 0.9971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9301f, 0.9847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9265f, 0.9518f, 0.9058f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8641f, 0.8673f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8324f, 0.7774f, 0.5302f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8959f, 0.7589f, 0.5644f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7669f, 0.6465f, 0.2254f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9092f, 0.9809f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9638f, 0.9866f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8880f, 0.8455f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8985f, 0.9168f, 0.8735f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8972f, 0.8142f, 0.3585f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7748f, 0.6956f, 0.2776f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, + 1.0000f, 0.8225f, 0.3945f, 0.0782f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9511f, + 1.0000f, 0.7299f, 0.2913f, 0.4359f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9609f, 0.9655f, + 1.0000f, 1.0000f, 0.9158f, 0.9525f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9034f, 0.9437f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8285f, 0.8472f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, + 1.0000f, 0.8305f, 0.9081f, 0.3712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, + 1.0000f, 0.8720f, 0.5899f, 0.1814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9545f, 0.9931f, + 1.0000f, 0.6172f, 0.3049f, 0.3185f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9869f, 0.9956f, + 1.0000f, 0.7030f, 0.2045f, 0.2621f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9336f, 0.9660f, + 1.0000f, 0.4456f, 0.1321f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9362f, 0.9237f, 0.9137f, + 1.0000f, 0.9978f, 0.9994f, 0.9972f, 1.0000f, 0.7825f, 0.5958f, 0.7100f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9994f, 0.9999f, 0.9596f, 1.0000f, 0.6555f, 0.7235f, 0.7391f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9813f, 0.9900f, 0.9893f, 1.0000f, 0.5442f, 0.9489f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9474f, 0.9789f, 0.8657f, 1.0000f, 0.7800f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8689f, 0.8608f, 0.9371f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7989f, 0.9345f, 0.8894f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5509f, 0.7616f, 0.9413f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6224f, 0.9539f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9996f, 0.9910f, 0.9126f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9993f, 0.9777f, 0.9677f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9742f, 0.8184f, 0.9022f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9496f, 0.9666f, 0.8766f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4904f, 0.8344f, 0.8907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6722f, 0.9649f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4988f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7966f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9828f, 0.9836f, 0.9737f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9571f, 0.9708f, 0.8363f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6326f, 0.8400f, 0.9797f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 1.0000f, + 1.0000f, 0.8011f, 0.9199f, 0.9627f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9997f, + 1.0000f, 0.5227f, 0.8704f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9998f, 0.9998f, + 1.0000f, 0.7449f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, 0.9879f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9603f, 0.9773f, 0.9246f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 0.9793f, 0.8558f, + 1.0000f, 0.8034f, 0.8795f, 0.9148f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, + 1.0000f, 0.9444f, 0.8099f, 0.8245f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, + 1.0000f, 0.5775f, 0.9010f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9992f, 0.9890f, + 1.0000f, 0.7330f, 0.9353f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9989f, 0.9208f, + 1.0000f, 0.5577f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9843f, 0.9953f, 0.9850f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9552f, 0.9863f, 0.8838f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9698f, 0.8056f, 0.8121f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9503f, 0.9189f, 0.8205f, + 1.0000f, 1.0000f, 0.9873f, 0.9857f, 1.0000f, 0.9178f, 0.8507f, 0.8382f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9970f, 0.9922f, 0.9983f, 1.0000f, 0.9621f, 0.7420f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9903f, 0.9578f, 0.9388f, 1.0000f, 0.9615f, 0.9935f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9703f, 0.9327f, 0.4553f, 1.0000f, 0.7920f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9718f, 0.8265f, 0.4155f, 1.0000f, 0.9584f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8853f, 0.5373f, 0.9948f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9747f, 0.7943f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9227f, 0.9274f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9840f, 0.9854f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9713f, 0.9944f, 0.9565f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9801f, 0.8419f, 0.5070f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8867f, 0.7361f, 0.5839f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9429f, 0.4051f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7897f, 0.6993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9805f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8489f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9785f, 0.9824f, 0.9532f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9832f, 0.9590f, 0.6880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, + 1.0000f, 0.9723f, 0.7066f, 0.8625f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9993f, + 1.0000f, 0.8947f, 0.4734f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9980f, + 1.0000f, 0.9115f, 0.9459f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9926f, 0.9967f, + 1.0000f, 0.4820f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9969f, 0.9990f, + 1.0000f, 0.9466f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9781f, 0.9898f, + 1.0000f, 0.9961f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9733f, 0.9905f, 0.9821f, + 1.0000f, 0.9769f, 0.9379f, 0.7643f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9982f, + 1.0000f, 0.9671f, 0.8810f, 0.7267f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9924f, + 1.0000f, 0.9632f, 0.6014f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9887f, 0.9977f, + 1.0000f, 0.8751f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9920f, 0.9913f, + 1.0000f, 0.9104f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.9895f, 0.9481f, + 1.0000f, 0.7561f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9876f, 0.9693f, 0.6275f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 0.9688f, 0.8934f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9817f, 0.9283f, 0.9318f, + 1.0000f, 0.9942f, 0.8437f, 0.5710f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9882f, 0.8163f, 0.7874f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3452f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7203f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8078f, 0.6763f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6681f, 0.9964f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6640f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9986f, 0.9984f, + 1.0000f, 0.9292f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, 0.9999f, 0.9908f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, 0.9991f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 1.0000f, 0.9760f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9069f, 0.7534f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.8824f, 0.9421f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9396f, 0.8921f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8575f, 0.9929f, 1.0000f, + 1.0000f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9728f, 0.9990f, 0.9986f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9860f, 1.0000f, 0.8781f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9218f, 0.5149f, 0.9405f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8541f, 0.6842f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6374f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9309f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_8x6[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6348f, 0.7860f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8285f, 0.9042f, + 1.0000f, 1.0000f, 1.0000f, 0.9940f, 1.0000f, 0.6847f, 0.7223f, 0.8700f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7983f, 0.9615f, + 1.0000f, 1.0000f, 0.9487f, 0.9920f, 1.0000f, 0.7690f, 0.7645f, 0.4879f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8948f, 0.8713f, + 1.0000f, 1.0000f, 0.9808f, 0.9956f, 1.0000f, 0.6912f, 0.7029f, 0.4162f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9254f, 0.9272f, 0.9100f, + 1.0000f, 1.0000f, 0.9263f, 0.9493f, 1.0000f, 0.7141f, 0.4679f, 0.4243f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9081f, 0.8499f, 0.5771f, + 1.0000f, 0.9382f, 0.9724f, 0.9625f, 1.0000f, 0.6704f, 0.2426f, 0.8042f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7798f, 0.8117f, 0.3822f, + 1.0000f, 1.0000f, 0.8969f, 0.9011f, 1.0000f, 0.6075f, 0.0672f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8203f, 0.5325f, 0.1476f, + 1.0000f, 0.8857f, 0.7943f, 0.5976f, 1.0000f, 0.3069f, 0.5075f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7599f, 0.3735f, 0.4746f, + 1.0000f, 1.0000f, 1.0000f, 0.9801f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9845f, 0.9983f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9469f, 0.9779f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9397f, 0.9546f, 0.8787f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8774f, 0.8991f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8555f, 0.8022f, 0.5612f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9128f, 0.7623f, 0.5264f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7776f, 0.6470f, 0.2700f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9338f, 0.9885f, 0.7429f, 1.0000f, 1.0000f, 1.0000f, 0.1977f, 1.0000f, 1.0000f, 1.0000f, 0.5823f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9716f, 0.9912f, 0.4944f, 1.0000f, 1.0000f, 1.0000f, 0.1297f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8980f, 0.8410f, 0.5386f, 1.0000f, 1.0000f, 1.0000f, 0.0899f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9109f, 0.9322f, 0.8569f, 0.2287f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9219f, 0.8348f, 0.3994f, 0.0352f, 1.0000f, 1.0000f, 1.0000f, 0.4610f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8003f, 0.7327f, 0.3909f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9937f, + 1.0000f, 0.8528f, 0.4078f, 0.1113f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9905f, + 1.0000f, 0.7249f, 0.2834f, 0.4398f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9907f, 0.9974f, + 1.0000f, 1.0000f, 0.9361f, 0.9707f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9353f, 0.9529f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8169f, 0.8394f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, + 1.0000f, 0.8470f, 0.8925f, 0.3268f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, + 1.0000f, 0.8903f, 0.6510f, 0.2565f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9698f, 0.9948f, + 1.0000f, 0.6741f, 0.3553f, 0.4470f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9914f, 0.9957f, + 1.0000f, 0.7196f, 0.1815f, 0.2957f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9463f, 0.9872f, + 1.0000f, 0.5503f, 0.1651f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9594f, 0.9600f, 0.9183f, + 1.0000f, 0.9981f, 0.9993f, 0.9973f, 1.0000f, 0.7922f, 0.6124f, 0.6880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9605f, 0.9689f, 0.9137f, + 1.0000f, 0.9995f, 0.9998f, 0.9579f, 1.0000f, 0.6777f, 0.7000f, 0.7301f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9511f, 0.9430f, 0.6550f, + 1.0000f, 0.9736f, 0.9870f, 0.9827f, 1.0000f, 0.5926f, 0.9517f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7169f, 0.6971f, 0.9410f, + 1.0000f, 0.9306f, 0.9752f, 0.8316f, 1.0000f, 0.7819f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7881f, 0.8799f, 0.9720f, + 1.0000f, 0.8762f, 0.8725f, 0.9568f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5139f, 0.9443f, 1.0000f, + 1.0000f, 0.8134f, 0.9505f, 0.9022f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7454f, 1.0000f, 1.0000f, + 1.0000f, 0.5445f, 0.8687f, 0.9246f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7085f, 0.9775f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9997f, 0.9926f, 0.9071f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9994f, 0.9836f, 0.9636f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9666f, 0.7840f, 0.8750f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9437f, 0.9589f, 0.8846f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5010f, 0.8914f, 0.9237f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7353f, 0.9848f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6666f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9853f, 0.9856f, 0.9685f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9646f, 0.9794f, 0.8363f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6430f, 0.8455f, 0.9740f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, + 1.0000f, 0.7963f, 0.9201f, 0.9620f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9996f, + 1.0000f, 0.6307f, 0.9061f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9999f, 0.9996f, + 1.0000f, 0.8379f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, 0.9883f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9928f, 0.9703f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9951f, 0.9656f, + 1.0000f, 0.8219f, 0.8738f, 0.9289f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 1.0000f, + 1.0000f, 0.9631f, 0.8080f, 0.8582f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 0.5874f, 0.9174f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9992f, 0.9768f, + 1.0000f, 0.7552f, 0.9297f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9980f, 0.8881f, + 1.0000f, 0.6589f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9824f, 0.9962f, 0.9895f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9535f, 0.9862f, 0.9032f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9744f, 0.8268f, 0.8937f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9562f, 0.9694f, 0.9210f, + 1.0000f, 1.0000f, 0.9818f, 0.9787f, 1.0000f, 0.9403f, 0.8649f, 0.8332f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9814f, 0.9821f, 0.9764f, + 1.0000f, 0.9979f, 0.9867f, 0.9976f, 1.0000f, 0.9573f, 0.7755f, 0.9998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9888f, 0.9811f, 0.9090f, + 1.0000f, 0.9953f, 0.9417f, 0.9001f, 1.0000f, 0.9680f, 0.9935f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9842f, 0.9390f, 0.9898f, + 1.0000f, 0.9783f, 0.9165f, 0.3171f, 1.0000f, 0.8236f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9748f, 0.8440f, 1.0000f, + 1.0000f, 0.9641f, 0.8061f, 0.3646f, 1.0000f, 0.9584f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9499f, 0.9878f, 1.0000f, + 1.0000f, 0.8596f, 0.5202f, 0.9982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8675f, 1.0000f, 1.0000f, + 1.0000f, 0.9424f, 0.5558f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9551f, 1.0000f, 1.0000f, + 1.0000f, 0.8252f, 0.8098f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9916f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9890f, 0.9947f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9902f, 0.9924f, 0.9712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9790f, 0.8151f, 0.4541f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9147f, 0.7504f, 0.6026f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9346f, 0.3459f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7528f, 0.6171f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9368f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5718f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9760f, 0.9859f, 0.9651f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9772f, 0.9756f, 0.7479f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, + 1.0000f, 0.9728f, 0.7114f, 0.9052f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9986f, + 1.0000f, 0.9156f, 0.4322f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9959f, + 1.0000f, 0.9280f, 0.9330f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9909f, 0.9963f, + 1.0000f, 0.4814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9984f, 1.0000f, + 1.0000f, 0.9192f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9864f, 0.9954f, + 1.0000f, 0.9481f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9900f, 0.9971f, 0.9833f, + 1.0000f, 0.9805f, 0.9456f, 0.8301f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.9992f, + 1.0000f, 0.9732f, 0.9119f, 0.7902f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 0.9851f, + 1.0000f, 0.9661f, 0.6627f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9893f, 0.9978f, + 1.0000f, 0.8869f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9931f, 0.9918f, 0.9880f, + 1.0000f, 0.8959f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 0.9540f, 0.9675f, + 1.0000f, 0.6941f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9830f, 0.9557f, 0.6218f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 0.9314f, 0.7057f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9523f, 0.8636f, 0.8425f, + 1.0000f, 0.9930f, 0.8822f, 0.6389f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8662f, 1.0000f, 1.0000f, + 1.0000f, 0.9922f, 0.8810f, 0.8485f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9450f, 1.0000f, 1.0000f, + 1.0000f, 0.2138f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6813f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8622f, 0.7379f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7275f, 0.9988f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7734f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9990f, 0.9986f, + 1.0000f, 0.9670f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 1.0000f, 0.9875f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9942f, 0.9991f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.9999f, 0.9475f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9228f, 0.7576f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9950f, 0.8892f, 0.9610f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8609f, 0.8186f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7668f, 0.9985f, 1.0000f, + 1.0000f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9798f, 0.9999f, 0.9964f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9839f, 1.0000f, 0.9375f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8542f, 0.3364f, 0.8834f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7404f, 0.6265f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5665f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8514f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_8x8[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6539f, 0.8057f, 1.0000f, 1.0000f, 0.8190f, 0.8664f, 1.0000f, 1.0000f, 0.9665f, 0.9926f, + 1.0000f, 1.0000f, 1.0000f, 0.9969f, 1.0000f, 0.7563f, 0.7444f, 0.8563f, 1.0000f, 0.8161f, 0.8706f, 0.8925f, 1.0000f, 1.0000f, 0.9863f, 0.9956f, + 1.0000f, 1.0000f, 0.9786f, 0.9960f, 1.0000f, 0.8529f, 0.8117f, 0.5924f, 1.0000f, 0.9100f, 0.8609f, 0.6746f, 1.0000f, 1.0000f, 0.9382f, 0.8726f, + 1.0000f, 1.0000f, 0.9941f, 0.9942f, 1.0000f, 0.7543f, 0.7979f, 0.4968f, 1.0000f, 0.8368f, 0.8493f, 0.5366f, 1.0000f, 0.9476f, 0.9487f, 0.9213f, + 1.0000f, 1.0000f, 0.9326f, 0.9588f, 1.0000f, 0.7205f, 0.6146f, 0.5412f, 1.0000f, 0.7849f, 0.6074f, 0.3232f, 1.0000f, 0.9498f, 0.8642f, 0.5125f, + 1.0000f, 0.9562f, 0.9712f, 0.9698f, 1.0000f, 0.7113f, 0.3712f, 0.9158f, 1.0000f, 0.7947f, 0.2448f, 0.9190f, 1.0000f, 0.8456f, 0.8102f, 0.4805f, + 1.0000f, 1.0000f, 0.8795f, 0.8987f, 1.0000f, 0.6447f, 0.1531f, 1.0000f, 1.0000f, 0.7065f, 0.0985f, 1.0000f, 1.0000f, 0.8736f, 0.4914f, 0.1851f, + 1.0000f, 0.8907f, 0.8010f, 0.5802f, 1.0000f, 0.5176f, 0.6629f, 1.0000f, 1.0000f, 0.4582f, 0.6110f, 1.0000f, 1.0000f, 0.7602f, 0.3314f, 0.5590f, + 1.0000f, 1.0000f, 1.0000f, 0.9792f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9762f, 0.9823f, + 1.0000f, 1.0000f, 0.9932f, 0.9990f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9638f, 0.9661f, + 1.0000f, 1.0000f, 0.9723f, 0.9817f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8969f, 0.9198f, + 1.0000f, 0.9642f, 0.9743f, 0.9091f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9040f, 0.9332f, 0.5633f, + 1.0000f, 1.0000f, 0.9022f, 0.9221f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9313f, 0.7040f, 0.2718f, + 1.0000f, 0.8716f, 0.8219f, 0.5843f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6991f, 0.4215f, 0.5021f, + 1.0000f, 0.9376f, 0.7749f, 0.5457f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8072f, 0.2258f, 0.3938f, + 1.0000f, 0.7882f, 0.6802f, 0.3150f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6250f, 0.2059f, 1.0000f, + 1.0000f, 1.0000f, 0.9626f, 0.9968f, 0.7963f, 1.0000f, 1.0000f, 1.0000f, 0.1272f, 1.0000f, 1.0000f, 1.0000f, 0.4638f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9916f, 0.9966f, 0.5502f, 1.0000f, 1.0000f, 1.0000f, 0.1745f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9345f, 0.8852f, 0.6478f, 1.0000f, 1.0000f, 1.0000f, 0.1132f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9523f, 0.9613f, 0.8943f, 0.2981f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9459f, 0.8916f, 0.4694f, 0.6417f, 1.0000f, 1.0000f, 1.0000f, 0.6216f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8176f, 0.8132f, 0.4860f, 0.0667f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, + 1.0000f, 0.8843f, 0.5074f, 0.2159f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9914f, + 1.0000f, 0.7714f, 0.3556f, 0.5719f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9919f, 0.9989f, + 1.0000f, 1.0000f, 0.9657f, 0.9848f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9705f, 0.9548f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8653f, 0.8815f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9874f, + 1.0000f, 0.9057f, 0.9228f, 0.4750f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, + 1.0000f, 0.9258f, 0.7361f, 0.3476f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9806f, 0.9961f, + 1.0000f, 0.7228f, 0.4080f, 0.6037f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 0.9939f, + 1.0000f, 0.7766f, 0.2539f, 0.4468f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9694f, 0.9909f, + 1.0000f, 0.6569f, 0.3635f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9709f, 0.9843f, 0.8996f, + 1.0000f, 0.9990f, 0.9988f, 0.9974f, 1.0000f, 0.7732f, 0.5884f, 0.7136f, 1.0000f, 0.8766f, 0.7273f, 0.7382f, 1.0000f, 0.9927f, 0.9959f, 0.9846f, + 1.0000f, 0.9998f, 0.9994f, 0.9592f, 1.0000f, 0.6600f, 0.6913f, 0.7403f, 1.0000f, 0.7931f, 0.7339f, 0.7464f, 1.0000f, 0.9809f, 0.9904f, 0.8674f, + 1.0000f, 0.9634f, 0.9833f, 0.9780f, 1.0000f, 0.6317f, 0.9605f, 1.0000f, 1.0000f, 0.6000f, 0.9691f, 1.0000f, 1.0000f, 0.7296f, 0.8695f, 0.9889f, + 1.0000f, 0.9265f, 0.9684f, 0.8394f, 1.0000f, 0.8342f, 1.0000f, 1.0000f, 1.0000f, 0.7914f, 1.0000f, 1.0000f, 1.0000f, 0.8552f, 0.9492f, 0.9841f, + 1.0000f, 0.8468f, 0.8233f, 0.9465f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6858f, 0.9236f, 1.0000f, + 1.0000f, 0.7816f, 0.9436f, 0.8598f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8685f, 1.0000f, 1.0000f, + 1.0000f, 0.4279f, 0.8898f, 0.9430f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7484f, 0.9759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9998f, 0.9944f, 0.9279f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9133f, 0.9370f, 0.9401f, + 1.0000f, 0.9998f, 0.9853f, 0.9719f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9828f, 0.8978f, 0.8870f, + 1.0000f, 0.9654f, 0.8275f, 0.9049f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6659f, 0.9125f, 1.0000f, + 1.0000f, 0.9543f, 0.9702f, 0.9320f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8247f, 0.9680f, 1.0000f, + 1.0000f, 0.4342f, 0.9083f, 0.9448f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7898f, 1.0000f, 1.0000f, + 1.0000f, 0.7523f, 0.9851f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7159f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7621f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9887f, 0.9883f, 0.9716f, 0.6774f, 1.0000f, 1.0000f, 1.0000f, 0.0827f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9740f, 0.9771f, 0.8586f, 0.2894f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7016f, 0.8776f, 0.9858f, 0.6509f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 0.8419f, 0.9442f, 0.9768f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, + 1.0000f, 0.7089f, 0.9272f, 1.0000f, 0.3396f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9999f, 0.9986f, + 1.0000f, 0.9031f, 1.0000f, 1.0000f, 0.2806f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9996f, 0.9676f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9955f, 0.9538f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9900f, 0.9726f, + 1.0000f, 0.8328f, 0.8756f, 0.9117f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.9557f, 0.8147f, 0.8540f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.6351f, 0.9388f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.9971f, 0.9579f, + 1.0000f, 0.8355f, 0.9618f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9951f, 0.8381f, + 1.0000f, 0.7696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9630f, 0.9870f, 0.9867f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9306f, 0.9646f, 0.8288f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9736f, 0.8205f, 0.9108f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9553f, 0.9650f, 0.9293f, + 1.0000f, 1.0000f, 0.9876f, 0.9872f, 1.0000f, 0.9596f, 0.8879f, 0.8431f, 1.0000f, 0.9601f, 0.9687f, 0.8805f, 1.0000f, 0.9907f, 0.9746f, 0.9831f, + 1.0000f, 0.9992f, 0.9938f, 0.9985f, 1.0000f, 0.9339f, 0.8026f, 0.9997f, 1.0000f, 0.9753f, 0.9166f, 1.0000f, 1.0000f, 0.9893f, 0.9936f, 0.7783f, + 1.0000f, 0.9947f, 0.9407f, 0.9358f, 1.0000f, 0.9798f, 0.9983f, 1.0000f, 1.0000f, 0.9783f, 0.9897f, 1.0000f, 1.0000f, 0.9825f, 0.8261f, 0.9503f, + 1.0000f, 0.9812f, 0.9413f, 0.4405f, 1.0000f, 0.8824f, 1.0000f, 1.0000f, 1.0000f, 0.9528f, 1.0000f, 1.0000f, 1.0000f, 0.9351f, 0.5546f, 1.0000f, + 1.0000f, 0.9820f, 0.7995f, 0.1638f, 1.0000f, 0.9508f, 1.0000f, 1.0000f, 1.0000f, 0.9777f, 1.0000f, 1.0000f, 1.0000f, 0.8934f, 0.8785f, 1.0000f, + 1.0000f, 0.8620f, 0.4525f, 0.9899f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5320f, 1.0000f, 1.0000f, + 1.0000f, 0.9570f, 0.3789f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8575f, 1.0000f, 1.0000f, + 1.0000f, 0.7658f, 0.5225f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8406f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9930f, 0.9978f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9895f, 0.9789f, 0.8960f, + 1.0000f, 0.9913f, 0.9935f, 0.9948f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9774f, 0.9583f, 0.8087f, + 1.0000f, 0.9865f, 0.9066f, 0.5677f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9733f, 0.7677f, 1.0000f, + 1.0000f, 0.9300f, 0.8444f, 0.7640f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9174f, 1.0000f, 1.0000f, + 1.0000f, 0.9673f, 0.4010f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9250f, 1.0000f, 1.0000f, + 1.0000f, 0.7799f, 0.6284f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6718f, 1.0000f, 1.0000f, + 1.0000f, 0.9150f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3864f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9803f, 0.9856f, 0.9765f, 0.6966f, 1.0000f, 1.0000f, 1.0000f, 0.5963f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9838f, 0.9801f, 0.8833f, 0.0503f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9929f, + 1.0000f, 0.9669f, 0.8042f, 0.9814f, 0.3067f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9972f, + 1.0000f, 0.9518f, 0.6181f, 1.0000f, 0.2356f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9973f, + 1.0000f, 0.9206f, 0.9182f, 1.0000f, 0.0271f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9976f, + 1.0000f, 0.5761f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9979f, 0.9991f, + 1.0000f, 0.8952f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9952f, 0.9970f, + 1.0000f, 0.8315f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9836f, 0.9924f, 0.9891f, + 1.0000f, 0.9749f, 0.9566f, 0.8746f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9984f, + 1.0000f, 0.9918f, 0.9364f, 0.8631f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9945f, + 1.0000f, 0.9795f, 0.7318f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9881f, 0.9902f, + 1.0000f, 0.9454f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9921f, 0.9609f, 0.9860f, + 1.0000f, 0.9424f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9471f, 0.9286f, + 1.0000f, 0.6940f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9756f, 0.9394f, 0.4148f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9243f, 0.6384f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9418f, 0.7866f, 0.7251f, + 1.0000f, 0.9982f, 0.9513f, 0.7424f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7182f, 1.0000f, 1.0000f, + 1.0000f, 0.9962f, 0.9482f, 0.9729f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9575f, 1.0000f, 1.0000f, + 1.0000f, 0.1408f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6689f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9533f, 0.9141f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8861f, 0.9996f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9005f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9999f, 0.9967f, + 1.0000f, 0.9949f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9993f, 0.9975f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9922f, 0.9999f, 0.9981f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9911f, 1.0000f, 0.8889f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9014f, 0.6886f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9885f, 0.8505f, 0.9074f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8481f, 0.7832f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7582f, 0.9994f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9997f, 0.9985f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9879f, 1.0000f, 0.9622f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8302f, 0.2629f, 0.8517f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7504f, 0.5273f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1955f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6830f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_8x10[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8029f, 0.8183f, 1.0000f, 1.0000f, 0.9742f, 0.9767f, 1.0000f, 1.0000f, 0.9905f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 0.9980f, 1.0000f, 0.7921f, 0.8421f, 0.8718f, 1.0000f, 0.9775f, 0.9700f, 0.9587f, 1.0000f, 1.0000f, 0.9598f, 0.9960f, + 1.0000f, 1.0000f, 0.9851f, 0.9976f, 1.0000f, 0.9128f, 0.9270f, 0.5965f, 1.0000f, 0.9576f, 0.9361f, 0.6235f, 1.0000f, 1.0000f, 0.9553f, 0.8776f, + 1.0000f, 1.0000f, 0.9891f, 0.9934f, 1.0000f, 0.8587f, 0.8324f, 0.4406f, 1.0000f, 0.9156f, 0.8737f, 0.5514f, 1.0000f, 0.9684f, 0.9671f, 0.8883f, + 1.0000f, 1.0000f, 0.9750f, 0.9595f, 1.0000f, 0.8490f, 0.7375f, 0.5859f, 1.0000f, 0.9053f, 0.6035f, 0.5065f, 1.0000f, 0.9668f, 0.9014f, 0.4294f, + 1.0000f, 0.9764f, 0.9914f, 0.9819f, 1.0000f, 0.8866f, 0.4180f, 0.8958f, 1.0000f, 0.8875f, 0.1874f, 0.8248f, 1.0000f, 0.8998f, 0.8468f, 0.4064f, + 1.0000f, 1.0000f, 0.9322f, 0.8785f, 1.0000f, 0.7309f, 0.2514f, 1.0000f, 1.0000f, 0.8512f, 0.0364f, 1.0000f, 1.0000f, 0.9233f, 0.5297f, 0.1973f, + 1.0000f, 0.9221f, 0.8143f, 0.4872f, 1.0000f, 0.6655f, 0.7173f, 1.0000f, 1.0000f, 0.5017f, 0.4773f, 1.0000f, 1.0000f, 0.8618f, 0.2848f, 0.4723f, + 1.0000f, 1.0000f, 1.0000f, 0.9927f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9644f, 0.9099f, 1.0000f, 1.0000f, 0.9884f, 0.9874f, + 1.0000f, 1.0000f, 0.9948f, 0.9953f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9661f, 0.9616f, 0.9121f, 1.0000f, 1.0000f, 0.9634f, 0.9756f, + 1.0000f, 1.0000f, 0.9733f, 0.9946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9459f, 0.8804f, 0.5593f, 1.0000f, 1.0000f, 0.9436f, 0.9328f, + 1.0000f, 0.9718f, 0.9917f, 0.9038f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8925f, 0.5749f, 0.4969f, 1.0000f, 0.9606f, 0.9630f, 0.6103f, + 1.0000f, 1.0000f, 0.9440f, 0.9468f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8892f, 0.2768f, 0.7770f, 1.0000f, 0.9674f, 0.8209f, 0.4515f, + 1.0000f, 0.9691f, 0.8813f, 0.6847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7242f, 0.2250f, 1.0000f, 1.0000f, 0.8156f, 0.4620f, 0.6569f, + 1.0000f, 0.9569f, 0.8545f, 0.5473f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7265f, 0.1574f, 1.0000f, 1.0000f, 0.8747f, 0.3429f, 0.5251f, + 1.0000f, 0.8917f, 0.7102f, 0.3149f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2067f, 1.0000f, 1.0000f, 1.0000f, 0.7788f, 0.4351f, 1.0000f, + 1.0000f, 1.0000f, 0.9703f, 0.9956f, 0.8934f, 1.0000f, 1.0000f, 1.0000f, 0.1472f, 1.0000f, 0.7219f, 0.7999f, 0.5341f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9893f, 0.9975f, 0.6766f, 1.0000f, 1.0000f, 1.0000f, 0.2599f, 0.7053f, 0.7889f, 0.7353f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9609f, 0.9149f, 0.7621f, 1.0000f, 1.0000f, 1.0000f, 0.1368f, 0.8577f, 0.7460f, 0.3756f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9658f, 0.9627f, 0.9022f, 0.4004f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8727f, 0.6202f, 0.6451f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9561f, 0.9246f, 0.5895f, 0.7541f, 1.0000f, 1.0000f, 1.0000f, 0.6683f, 0.7640f, 0.1675f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9240f, 0.9077f, 0.6001f, 0.1155f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6298f, 0.7003f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, + 1.0000f, 0.9195f, 0.5786f, 0.2998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7287f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, + 1.0000f, 0.8974f, 0.3820f, 0.6329f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0921f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.9999f, + 1.0000f, 1.0000f, 0.9591f, 0.9780f, 0.0790f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9772f, 0.9454f, 0.5930f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9294f, 0.9046f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, + 1.0000f, 0.9499f, 0.9426f, 0.5112f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, + 1.0000f, 0.9486f, 0.8566f, 0.4568f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9868f, 0.9988f, + 1.0000f, 0.8639f, 0.5205f, 0.6793f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9911f, + 1.0000f, 0.8849f, 0.3361f, 0.5633f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9849f, 0.9931f, + 1.0000f, 0.7905f, 0.4237f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9816f, 0.9876f, 0.8698f, + 1.0000f, 0.9989f, 0.9989f, 0.9988f, 1.0000f, 0.7937f, 0.5554f, 0.6900f, 1.0000f, 0.9371f, 0.8900f, 0.9311f, 1.0000f, 0.9919f, 0.9940f, 0.9786f, + 1.0000f, 0.9999f, 0.9999f, 0.9753f, 1.0000f, 0.6421f, 0.6978f, 0.7439f, 1.0000f, 0.9030f, 0.9381f, 0.9584f, 1.0000f, 0.9715f, 0.9928f, 0.8669f, + 1.0000f, 0.9565f, 0.9811f, 0.9730f, 1.0000f, 0.6169f, 0.9525f, 1.0000f, 1.0000f, 0.7678f, 0.9350f, 1.0000f, 1.0000f, 0.6820f, 0.8629f, 0.9620f, + 1.0000f, 0.9107f, 0.9602f, 0.8299f, 1.0000f, 0.8044f, 1.0000f, 1.0000f, 1.0000f, 0.9189f, 1.0000f, 1.0000f, 1.0000f, 0.8287f, 0.9176f, 0.9853f, + 1.0000f, 0.8966f, 0.8608f, 0.9759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7126f, 0.9069f, 1.0000f, + 1.0000f, 0.8337f, 0.9482f, 0.9412f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8261f, 1.0000f, 1.0000f, + 1.0000f, 0.3221f, 0.7839f, 0.9339f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7150f, 0.9169f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9995f, 0.9920f, 0.9421f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7562f, 0.7331f, 0.9114f, 1.0000f, 0.9345f, 0.9529f, 0.9770f, + 1.0000f, 0.9997f, 0.9897f, 0.9678f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8058f, 0.8708f, 0.9904f, 1.0000f, 0.9938f, 0.9387f, 0.9778f, + 1.0000f, 0.9681f, 0.8433f, 0.8991f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8349f, 1.0000f, 1.0000f, 1.0000f, 0.7753f, 0.9736f, 1.0000f, + 1.0000f, 0.9613f, 0.9623f, 0.9508f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9317f, 0.9888f, 1.0000f, + 1.0000f, 0.4921f, 0.9355f, 0.9739f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8222f, 1.0000f, 1.0000f, + 1.0000f, 0.8235f, 0.9872f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7805f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7873f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9857f, 0.9886f, 0.9654f, 0.7953f, 1.0000f, 1.0000f, 1.0000f, 0.1775f, 0.5710f, 0.6069f, 0.9796f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9804f, 0.9862f, 0.8766f, 0.4122f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5823f, 0.8115f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7581f, 0.8840f, 0.9909f, 0.8087f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, + 1.0000f, 0.8409f, 0.9431f, 0.9835f, 0.0191f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 0.8014f, 0.9521f, 1.0000f, 0.5430f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9996f, 0.9978f, + 1.0000f, 0.9366f, 1.0000f, 1.0000f, 0.3074f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9402f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9900f, 0.9084f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9806f, 0.9464f, + 1.0000f, 0.8397f, 0.8942f, 0.9202f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, + 1.0000f, 0.9557f, 0.8101f, 0.8822f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6598f, 0.9392f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9943f, 0.9572f, + 1.0000f, 0.8386f, 0.9648f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9955f, 0.8170f, + 1.0000f, 0.8689f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9706f, 0.9846f, 0.9860f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9061f, 0.9855f, 0.8445f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9397f, 0.7659f, 0.8534f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9258f, 0.9512f, 0.9162f, + 1.0000f, 1.0000f, 0.9991f, 0.9992f, 1.0000f, 0.9922f, 0.8479f, 0.7734f, 1.0000f, 0.9783f, 0.9724f, 0.8501f, 1.0000f, 0.9970f, 0.9930f, 0.9761f, + 1.0000f, 0.9967f, 0.9997f, 0.9997f, 1.0000f, 0.9491f, 0.7418f, 1.0000f, 1.0000f, 0.9828f, 0.8456f, 1.0000f, 1.0000f, 0.9844f, 0.9944f, 0.7716f, + 1.0000f, 0.9987f, 0.9954f, 0.9300f, 1.0000f, 0.9840f, 0.9978f, 1.0000f, 1.0000f, 0.9799f, 0.9687f, 1.0000f, 1.0000f, 0.9814f, 0.7697f, 0.8831f, + 1.0000f, 0.9925f, 0.9694f, 0.4461f, 1.0000f, 0.8073f, 1.0000f, 1.0000f, 1.0000f, 0.7856f, 1.0000f, 1.0000f, 1.0000f, 0.9709f, 0.3497f, 1.0000f, + 1.0000f, 0.9958f, 0.8598f, 0.2684f, 1.0000f, 0.9252f, 1.0000f, 1.0000f, 1.0000f, 0.8982f, 1.0000f, 1.0000f, 1.0000f, 0.9288f, 0.6711f, 1.0000f, + 1.0000f, 0.9416f, 0.5159f, 0.9998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3627f, 1.0000f, 1.0000f, + 1.0000f, 0.9882f, 0.2341f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8555f, 1.0000f, 1.0000f, + 1.0000f, 0.8129f, 0.3944f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6267f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9935f, 0.9981f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9912f, 0.9473f, 0.9974f, 1.0000f, 0.9977f, 0.9580f, 0.8659f, + 1.0000f, 0.9981f, 0.9985f, 0.9947f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9824f, 0.8374f, 1.0000f, 1.0000f, 0.9890f, 0.9333f, 0.7396f, + 1.0000f, 0.9979f, 0.9477f, 0.6391f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9712f, 1.0000f, 1.0000f, 1.0000f, 0.9916f, 0.6136f, 1.0000f, + 1.0000f, 0.9533f, 0.8312f, 0.7521f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7984f, 1.0000f, 1.0000f, 1.0000f, 0.9305f, 1.0000f, 1.0000f, + 1.0000f, 0.9826f, 0.4823f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9537f, 1.0000f, 1.0000f, + 1.0000f, 0.9006f, 0.6627f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4672f, 1.0000f, 1.0000f, + 1.0000f, 0.9516f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2923f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9745f, 0.9788f, 0.9727f, 0.8196f, 1.0000f, 1.0000f, 1.0000f, 0.3882f, 0.9936f, 0.8950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9949f, 0.9821f, 0.9276f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9641f, 0.9907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 0.9801f, 0.8361f, 0.9549f, 0.7028f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9651f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9747f, 1.0000f, + 1.0000f, 0.9878f, 0.6360f, 1.0000f, 0.2159f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9866f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9880f, + 1.0000f, 0.9637f, 0.9227f, 1.0000f, 0.0654f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9983f, + 1.0000f, 0.6952f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9991f, + 1.0000f, 0.9208f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9971f, + 1.0000f, 0.7969f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9952f, 0.9495f, + 1.0000f, 0.9959f, 0.9664f, 0.8523f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9992f, + 1.0000f, 0.9831f, 0.9182f, 0.8274f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9957f, + 1.0000f, 0.9870f, 0.7501f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9996f, + 1.0000f, 0.9092f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9902f, 0.9837f, + 1.0000f, 0.9504f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9942f, 0.9895f, 0.9376f, + 1.0000f, 0.7078f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 0.9809f, 0.3562f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.8909f, 0.3292f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9264f, 0.7196f, 0.5386f, + 1.0000f, 0.9997f, 0.9794f, 0.8649f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6926f, 1.0000f, 1.0000f, + 1.0000f, 0.9996f, 0.9450f, 0.9721f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9214f, 1.0000f, 1.0000f, + 1.0000f, 0.2427f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6540f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9445f, 0.9545f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 1.0000f, 1.0000f, + 1.0000f, 0.9282f, 0.9993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8857f, 1.0000f, 1.0000f, 0.7480f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9994f, 0.9986f, + 1.0000f, 0.9791f, 1.0000f, 1.0000f, 0.1039f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9842f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0517f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9833f, 0.9984f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9864f, 0.9998f, 0.8794f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.8679f, 0.6739f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.9142f, 0.9407f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7822f, 0.6874f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6511f, 0.9899f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9932f, 0.9994f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9697f, 1.0000f, 0.9541f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9135f, 0.3692f, 0.8756f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7601f, 0.5671f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1263f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6481f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_8x12[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8054f, 0.8341f, 1.0000f, 1.0000f, 0.9810f, 0.9675f, 1.0000f, 1.0000f, 0.9943f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 0.9986f, 1.0000f, 0.8624f, 0.8820f, 0.8375f, 1.0000f, 0.9572f, 0.9701f, 0.9819f, 1.0000f, 1.0000f, 0.9868f, 0.9979f, + 1.0000f, 1.0000f, 0.9915f, 0.9972f, 1.0000f, 0.9009f, 0.9330f, 0.6438f, 1.0000f, 0.9640f, 0.9394f, 0.6551f, 1.0000f, 1.0000f, 0.9521f, 0.8586f, + 1.0000f, 1.0000f, 0.9962f, 0.9975f, 1.0000f, 0.9383f, 0.8132f, 0.4939f, 1.0000f, 0.9373f, 0.9017f, 0.5792f, 1.0000f, 0.9525f, 0.9604f, 0.8652f, + 1.0000f, 1.0000f, 0.9899f, 0.9672f, 1.0000f, 0.9053f, 0.7622f, 0.5825f, 1.0000f, 0.9208f, 0.6175f, 0.5434f, 1.0000f, 0.9583f, 0.9232f, 0.3895f, + 1.0000f, 0.9765f, 0.9813f, 0.9742f, 1.0000f, 0.8845f, 0.4758f, 0.8948f, 1.0000f, 0.8595f, 0.1803f, 0.8282f, 1.0000f, 0.9038f, 0.8196f, 0.3837f, + 1.0000f, 1.0000f, 0.9436f, 0.9136f, 1.0000f, 0.7854f, 0.3658f, 1.0000f, 1.0000f, 0.8419f, 0.0601f, 1.0000f, 1.0000f, 0.9478f, 0.5757f, 0.2737f, + 1.0000f, 0.9466f, 0.8397f, 0.5278f, 1.0000f, 0.7148f, 0.7692f, 1.0000f, 1.0000f, 0.5071f, 0.4518f, 1.0000f, 1.0000f, 0.8901f, 0.3415f, 0.5509f, + 1.0000f, 1.0000f, 1.0000f, 0.9940f, 0.6145f, 1.0000f, 1.0000f, 1.0000f, 0.8495f, 1.0000f, 0.9607f, 0.9220f, 0.6381f, 1.0000f, 0.9945f, 0.9969f, + 1.0000f, 1.0000f, 0.9961f, 0.9995f, 0.8246f, 1.0000f, 1.0000f, 1.0000f, 0.8080f, 0.9440f, 0.9634f, 0.9238f, 0.4567f, 1.0000f, 0.9863f, 0.9898f, + 1.0000f, 1.0000f, 0.9779f, 0.9934f, 0.8184f, 1.0000f, 1.0000f, 1.0000f, 0.5358f, 0.9418f, 0.9123f, 0.6323f, 0.8093f, 1.0000f, 0.9357f, 0.8725f, + 1.0000f, 0.9882f, 0.9885f, 0.9279f, 0.8067f, 1.0000f, 1.0000f, 1.0000f, 0.2212f, 0.9002f, 0.5891f, 0.6235f, 1.0000f, 0.9449f, 0.9389f, 0.4420f, + 1.0000f, 1.0000f, 0.9453f, 0.9335f, 0.7823f, 1.0000f, 1.0000f, 1.0000f, 0.7775f, 0.8837f, 0.3086f, 0.7792f, 1.0000f, 0.9506f, 0.7884f, 0.2665f, + 1.0000f, 0.9760f, 0.8760f, 0.6893f, 0.1970f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7395f, 0.3598f, 1.0000f, 1.0000f, 0.8209f, 0.3287f, 0.5858f, + 1.0000f, 0.9723f, 0.8987f, 0.6113f, 0.1450f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7169f, 0.1631f, 1.0000f, 1.0000f, 0.8484f, 0.1888f, 0.3476f, + 1.0000f, 0.9176f, 0.7511f, 0.3951f, 0.6660f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1357f, 1.0000f, 1.0000f, 1.0000f, 0.7473f, 0.2879f, 1.0000f, + 1.0000f, 1.0000f, 0.9762f, 0.9920f, 0.9074f, 1.0000f, 1.0000f, 1.0000f, 0.2133f, 1.0000f, 0.9494f, 0.9445f, 0.6467f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9911f, 0.9973f, 0.7082f, 1.0000f, 1.0000f, 1.0000f, 0.3537f, 0.9547f, 0.8803f, 0.7657f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9794f, 0.9268f, 0.7942f, 1.0000f, 1.0000f, 1.0000f, 0.2592f, 0.9490f, 0.7293f, 0.4615f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9852f, 0.9715f, 0.9319f, 0.5156f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9422f, 0.5546f, 0.7314f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9558f, 0.9510f, 0.6410f, 0.7355f, 1.0000f, 1.0000f, 1.0000f, 0.7273f, 0.8662f, 0.1062f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9482f, 0.9088f, 0.6352f, 0.2368f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6051f, 0.6687f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, + 1.0000f, 0.9565f, 0.6265f, 0.4370f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7675f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, + 1.0000f, 0.9130f, 0.5197f, 0.7567f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0320f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9985f, + 1.0000f, 1.0000f, 0.9835f, 0.9822f, 0.2443f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8795f, 0.8615f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9666f, 0.9486f, 0.4166f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9413f, 0.9189f, 0.5618f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9150f, 0.9156f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8861f, 0.5027f, 0.5653f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, + 1.0000f, 0.9624f, 0.9431f, 0.5723f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8716f, 0.3154f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, + 1.0000f, 0.9621f, 0.8689f, 0.4850f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7434f, 0.2053f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9953f, + 1.0000f, 0.8925f, 0.5238f, 0.7037f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4270f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9931f, + 1.0000f, 0.9169f, 0.4711f, 0.6633f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6942f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9865f, 0.9896f, + 1.0000f, 0.8536f, 0.5318f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1541f, 1.0000f, 1.0000f, 1.0000f, 0.9824f, 0.9928f, 0.8743f, + 1.0000f, 0.9989f, 0.9992f, 0.9987f, 1.0000f, 0.7839f, 0.5396f, 0.6792f, 1.0000f, 0.9698f, 0.9081f, 0.9726f, 1.0000f, 0.9887f, 0.9854f, 0.9656f, + 1.0000f, 0.9996f, 0.9999f, 0.9842f, 1.0000f, 0.6523f, 0.6740f, 0.7211f, 1.0000f, 0.9102f, 0.9398f, 0.9600f, 1.0000f, 0.9614f, 0.9859f, 0.8294f, + 1.0000f, 0.9744f, 0.9846f, 0.9787f, 1.0000f, 0.6818f, 0.9663f, 1.0000f, 1.0000f, 0.7986f, 0.9517f, 1.0000f, 1.0000f, 0.6294f, 0.8430f, 0.9362f, + 1.0000f, 0.9067f, 0.9579f, 0.8318f, 1.0000f, 0.8040f, 1.0000f, 1.0000f, 1.0000f, 0.9408f, 1.0000f, 1.0000f, 1.0000f, 0.7870f, 0.8853f, 0.9880f, + 1.0000f, 0.8786f, 0.8566f, 0.9533f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7104f, 0.9163f, 1.0000f, + 1.0000f, 0.8119f, 0.9631f, 0.9352f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8634f, 1.0000f, 1.0000f, + 1.0000f, 0.3352f, 0.8027f, 0.9576f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7252f, 0.9341f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9983f, 0.9966f, 0.9474f, 0.5114f, 1.0000f, 1.0000f, 1.0000f, 0.9659f, 0.8013f, 0.8546f, 0.9908f, 1.0000f, 0.9024f, 0.9457f, 0.9647f, + 1.0000f, 0.9998f, 0.9923f, 0.9808f, 0.6019f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8576f, 0.9529f, 0.9963f, 1.0000f, 0.9891f, 0.9313f, 0.9637f, + 1.0000f, 0.9769f, 0.8680f, 0.9116f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8917f, 1.0000f, 1.0000f, 1.0000f, 0.6990f, 0.9182f, 1.0000f, + 1.0000f, 0.9678f, 0.9597f, 0.9728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8812f, 0.9653f, 1.0000f, + 1.0000f, 0.4895f, 0.9250f, 0.9739f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6843f, 1.0000f, 1.0000f, + 1.0000f, 0.8107f, 0.9844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8452f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8474f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9932f, 0.9925f, 0.9784f, 0.8222f, 1.0000f, 1.0000f, 1.0000f, 0.0960f, 0.5923f, 0.7999f, 0.9906f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9736f, 0.9789f, 0.8734f, 0.3778f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7415f, 0.9627f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7759f, 0.9273f, 0.9974f, 0.7928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.8933f, 0.9514f, 0.9876f, 0.0163f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, + 1.0000f, 0.8329f, 0.9586f, 1.0000f, 0.5472f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9988f, 0.9967f, + 1.0000f, 0.9569f, 1.0000f, 1.0000f, 0.3018f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9997f, 0.9201f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9754f, 0.8909f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9772f, 0.9427f, + 1.0000f, 0.8671f, 0.8698f, 0.9346f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6579f, 0.8707f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9551f, 0.8258f, 0.8505f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7726f, 0.9806f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6966f, 0.9669f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9968f, 0.9544f, + 1.0000f, 0.8778f, 0.9767f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.8234f, + 1.0000f, 0.8964f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9325f, 0.9752f, 0.9720f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8893f, 0.9540f, 0.8171f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9296f, 0.7743f, 0.8364f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9368f, 0.9470f, 0.9262f, + 1.0000f, 1.0000f, 0.9992f, 0.9995f, 1.0000f, 0.9889f, 0.8829f, 0.7604f, 1.0000f, 0.9562f, 0.9837f, 0.7971f, 1.0000f, 0.9850f, 0.9747f, 0.9826f, + 1.0000f, 1.0000f, 0.9999f, 0.9990f, 1.0000f, 0.9590f, 0.7585f, 1.0000f, 1.0000f, 0.9950f, 0.7899f, 0.9999f, 1.0000f, 0.9989f, 0.9927f, 0.7375f, + 1.0000f, 0.9976f, 0.9782f, 0.9749f, 1.0000f, 0.9774f, 0.9980f, 1.0000f, 1.0000f, 0.9681f, 0.9143f, 1.0000f, 1.0000f, 0.9965f, 0.7060f, 0.7640f, + 1.0000f, 0.9986f, 0.9883f, 0.5689f, 1.0000f, 0.8158f, 1.0000f, 1.0000f, 1.0000f, 0.6917f, 1.0000f, 1.0000f, 1.0000f, 0.9833f, 0.2291f, 1.0000f, + 1.0000f, 0.9984f, 0.8769f, 0.1717f, 1.0000f, 0.9378f, 1.0000f, 1.0000f, 1.0000f, 0.8941f, 1.0000f, 1.0000f, 1.0000f, 0.9195f, 0.7014f, 1.0000f, + 1.0000f, 0.9302f, 0.4805f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3718f, 1.0000f, 1.0000f, + 1.0000f, 0.9918f, 0.3221f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8643f, 1.0000f, 1.0000f, + 1.0000f, 0.8526f, 0.4469f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6205f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9970f, 0.9980f, 0.9801f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9831f, 0.8994f, 0.9731f, 1.0000f, 0.9949f, 0.9799f, 0.8352f, + 1.0000f, 0.9973f, 0.9985f, 0.9954f, 0.8885f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9856f, 0.7530f, 1.0000f, 1.0000f, 0.9839f, 0.9403f, 0.5955f, + 1.0000f, 0.9998f, 0.9291f, 0.7548f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9796f, 1.0000f, 1.0000f, 1.0000f, 0.9757f, 0.4218f, 1.0000f, + 1.0000f, 0.9684f, 0.9109f, 0.9095f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6495f, 1.0000f, 1.0000f, 1.0000f, 0.8515f, 1.0000f, 1.0000f, + 1.0000f, 0.9930f, 0.5582f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8972f, 1.0000f, 1.0000f, + 1.0000f, 0.8751f, 0.6868f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1262f, 1.0000f, 1.0000f, + 1.0000f, 0.9777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4060f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9995f, 0.9921f, 0.9718f, 0.8408f, 1.0000f, 1.0000f, 1.0000f, 0.4320f, 0.9894f, 0.8306f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9971f, 0.9815f, 0.9308f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9791f, 0.9593f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9861f, 0.8463f, 0.9939f, 0.7454f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9686f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9870f, 0.9941f, + 1.0000f, 0.9867f, 0.6766f, 1.0000f, 0.2518f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9644f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9912f, + 1.0000f, 0.9828f, 0.9712f, 1.0000f, 0.1163f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9707f, 0.9892f, + 1.0000f, 0.7190f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9978f, 0.9872f, + 1.0000f, 0.9214f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 0.9958f, + 1.0000f, 0.7808f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.9917f, 0.9536f, + 1.0000f, 0.9956f, 0.9610f, 0.8956f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9689f, 0.8605f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9977f, + 1.0000f, 0.9944f, 0.9244f, 0.7913f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9462f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9878f, + 1.0000f, 0.9874f, 0.7957f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9998f, + 1.0000f, 0.9226f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9947f, 0.9734f, + 1.0000f, 0.9555f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9848f, 0.8869f, + 1.0000f, 0.7709f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9914f, 0.9617f, 0.2949f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, 0.9285f, 0.2808f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9709f, 0.7126f, 0.4007f, + 1.0000f, 0.9995f, 0.9650f, 0.9031f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5987f, 1.0000f, 1.0000f, + 1.0000f, 0.9999f, 0.9803f, 0.9955f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8877f, 1.0000f, 1.0000f, + 1.0000f, 0.4113f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7492f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9704f, 0.9502f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9498f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9256f, 1.0000f, 1.0000f, 0.7334f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, + 1.0000f, 0.9935f, 1.0000f, 1.0000f, 0.0731f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9817f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0468f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9692f, 0.9959f, 0.9901f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9903f, 0.9997f, 0.9046f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.8441f, 0.6082f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9952f, 0.8270f, 0.8556f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8145f, 0.6606f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6713f, 0.9909f, 1.0000f, + 1.0000f, 0.9997f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 1.0000f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9904f, 1.0000f, 0.9695f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8979f, 0.4663f, 0.9060f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8386f, 0.7231f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0849f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4984f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_10x4[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8283f, 0.9411f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9911f, 1.0000f, 0.8198f, 0.8943f, 0.9580f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9666f, 0.9914f, 1.0000f, 0.8649f, 0.7945f, 0.3479f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9856f, 0.9971f, 1.0000f, 0.7514f, 0.7303f, 0.3081f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8956f, 0.9461f, 1.0000f, 0.7426f, 0.3814f, 0.2020f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9385f, 0.9530f, 0.9764f, 1.0000f, 0.6902f, 0.0741f, 0.6157f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9734f, 1.0000f, 1.0000f, 0.7894f, 0.8086f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9724f, 0.9930f, 1.0000f, 0.8017f, 0.8803f, 0.8262f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9377f, 0.9777f, 1.0000f, 0.7655f, 0.7131f, 0.3217f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9368f, 0.9485f, 0.8846f, 1.0000f, 0.7204f, 0.2192f, 0.2356f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8514f, 0.9082f, 1.0000f, 0.7237f, 0.1048f, 0.4972f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8633f, 0.7710f, 0.6434f, 1.0000f, 0.3704f, 0.1327f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9224f, 0.9768f, 1.0000f, 1.0000f, 0.5507f, 0.7736f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9672f, 0.9919f, 1.0000f, 0.5135f, 0.6036f, 0.5645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8696f, 0.8364f, 1.0000f, 0.6584f, 0.4134f, 0.1824f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8861f, 0.9172f, 0.8459f, 1.0000f, 0.6485f, 0.3593f, 0.5054f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8995f, 0.8177f, 0.4801f, 1.0000f, 0.0383f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7790f, 0.7816f, 0.2803f, 1.0000f, 0.1601f, 0.2510f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9816f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9117f, 0.9634f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9093f, 0.9685f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8421f, 0.8665f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9935f, + 1.0000f, 0.8383f, 0.9058f, 0.4236f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9937f, + 1.0000f, 0.8832f, 0.6727f, 0.2658f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9523f, 0.9828f, + 1.0000f, 0.6941f, 0.4888f, 0.3352f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9696f, 0.9845f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9963f, 0.9989f, 0.9966f, 1.0000f, 0.8727f, 0.8344f, 0.9331f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9995f, 0.9999f, 0.9627f, 1.0000f, 0.7919f, 0.9244f, 0.9284f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9842f, 0.9923f, 0.9895f, 1.0000f, 0.5780f, 0.8712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9678f, 0.9835f, 0.8817f, 1.0000f, 0.7683f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9293f, 0.8477f, 0.9139f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8601f, 0.9070f, 0.9350f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9983f, 0.9801f, 0.8773f, 1.0000f, 0.5911f, 0.7167f, 0.9500f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9982f, 0.9702f, 0.9394f, 1.0000f, 0.7056f, 0.8303f, 0.9477f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9641f, 0.7485f, 0.8681f, 1.0000f, 0.6632f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9214f, 0.9538f, 0.8440f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5435f, 0.7600f, 0.9234f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6215f, 0.9654f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9781f, 0.9849f, 0.9729f, 1.0000f, 0.4620f, 0.6327f, 0.9182f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9594f, 0.9749f, 0.8132f, 1.0000f, 0.5214f, 0.8916f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6381f, 0.7969f, 0.9552f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 0.7763f, 0.8742f, 0.9428f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, + 1.0000f, 0.4032f, 0.9033f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9881f, 0.9926f, 0.9956f, + 1.0000f, 0.7018f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9939f, 0.9045f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8617f, 0.9312f, 0.9608f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 1.0000f, + 1.0000f, 0.9785f, 0.9020f, 0.8888f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, + 1.0000f, 0.6773f, 0.9341f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9990f, 0.9906f, + 1.0000f, 0.8040f, 0.9322f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9988f, 0.9264f, + 1.0000f, 0.7270f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9793f, 0.9820f, 0.9508f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9690f, 0.9718f, 0.7572f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9965f, 0.9916f, 1.0000f, 0.9614f, 0.8402f, 0.6818f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9981f, 0.9921f, 0.9984f, 1.0000f, 0.9161f, 0.6981f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9986f, 0.9621f, 0.9573f, 1.0000f, 0.9105f, 0.9420f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9869f, 0.9444f, 0.6097f, 1.0000f, 0.5289f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9813f, 0.9566f, 0.8109f, 1.0000f, 0.9587f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9773f, 0.8567f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9878f, 0.9838f, 1.0000f, 0.9493f, 0.7456f, 0.9903f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9859f, 0.9852f, 0.9008f, 1.0000f, 0.9274f, 0.6861f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9809f, 0.8241f, 0.4433f, 1.0000f, 0.9303f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8929f, 0.7093f, 0.5576f, 1.0000f, 0.7397f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9759f, 0.7628f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9193f, 0.9128f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9872f, 0.9601f, 0.9150f, 1.0000f, 0.9453f, 0.7993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9739f, 0.9403f, 0.5712f, 1.0000f, 0.8902f, 0.9824f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9469f, 0.6535f, 0.7335f, 1.0000f, 0.9647f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9994f, + 1.0000f, 0.8532f, 0.2943f, 1.0000f, 1.0000f, 0.9955f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9990f, + 1.0000f, 0.9436f, 0.9901f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9713f, 0.9951f, + 1.0000f, 0.7868f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.9962f, 0.9975f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9797f, 0.9254f, 0.7543f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.9985f, + 1.0000f, 0.9545f, 0.8969f, 0.6271f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.9941f, + 1.0000f, 0.9660f, 0.4714f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9898f, 0.9974f, + 1.0000f, 0.8063f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9932f, 0.9887f, 0.9945f, + 1.0000f, 0.9707f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9893f, 0.9884f, 0.9754f, + 1.0000f, 0.8982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9890f, 0.8584f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9943f, 0.8323f, 0.5846f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9790f, 0.8495f, 0.8154f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5973f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8875f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6680f, 0.3923f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4527f, 0.9831f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4335f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9997f, 0.9996f, + 1.0000f, 0.7842f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9998f, 0.9947f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 1.0000f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 1.0000f, 0.9909f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9516f, 0.8758f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9928f, 0.9559f, 0.9359f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9862f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9805f, 0.9980f, 0.9949f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9866f, 0.9995f, 0.8550f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9203f, 0.5363f, 0.9744f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8220f, 0.7366f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8788f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9875f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_10x5[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8462f, 0.9403f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9942f, 1.0000f, 0.8593f, 0.9155f, 0.9673f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9628f, 0.9948f, 1.0000f, 0.8912f, 0.8324f, 0.4420f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9895f, 0.9959f, 1.0000f, 0.7946f, 0.7847f, 0.3829f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9332f, 0.9648f, 1.0000f, 0.7965f, 0.3746f, 0.2759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9547f, 0.9812f, 0.9758f, 1.0000f, 0.7256f, 0.0857f, 0.6373f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8371f, 0.9247f, 1.0000f, 0.6694f, 0.0608f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9051f, 0.8356f, 0.7286f, 1.0000f, 0.2660f, 0.5139f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9774f, 1.0000f, 1.0000f, 0.8133f, 0.8022f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9778f, 0.9926f, 1.0000f, 0.8240f, 0.8854f, 0.8387f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9450f, 0.9853f, 1.0000f, 0.8169f, 0.7423f, 0.3906f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9430f, 0.9541f, 0.8741f, 1.0000f, 0.7591f, 0.3143f, 0.4061f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8842f, 0.8753f, 1.0000f, 0.7614f, 0.1271f, 0.5615f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8418f, 0.7723f, 0.5785f, 1.0000f, 0.5261f, 0.1800f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8956f, 0.8096f, 0.6461f, 1.0000f, 0.4489f, 0.1966f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8151f, 0.7369f, 0.2098f, 1.0000f, 0.1456f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9346f, 0.9885f, 1.0000f, 1.0000f, 0.5322f, 0.7701f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9782f, 0.9950f, 1.0000f, 0.5014f, 0.5558f, 0.5947f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8967f, 0.8402f, 1.0000f, 0.6731f, 0.5728f, 0.2558f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9061f, 0.9198f, 0.8805f, 1.0000f, 0.7038f, 0.5078f, 0.6543f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9206f, 0.8307f, 0.3321f, 1.0000f, 0.6240f, 0.1081f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8115f, 0.7448f, 0.2857f, 1.0000f, 0.2954f, 0.5840f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, + 1.0000f, 0.8648f, 0.5500f, 0.1633f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9530f, + 1.0000f, 0.7765f, 0.3662f, 0.5201f, 1.0000f, 0.0325f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9668f, 0.9602f, + 1.0000f, 1.0000f, 0.9173f, 0.9512f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9223f, 0.9575f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8830f, 0.9010f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, + 1.0000f, 0.8564f, 0.9181f, 0.4820f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, + 1.0000f, 0.9138f, 0.6836f, 0.2226f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9737f, 0.9976f, + 1.0000f, 0.7134f, 0.3233f, 0.4624f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9882f, 0.9936f, + 1.0000f, 0.7679f, 0.3050f, 0.4281f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9286f, 0.9697f, + 1.0000f, 0.6149f, 0.2340f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9481f, 0.9375f, 0.9271f, + 1.0000f, 0.9980f, 0.9996f, 0.9967f, 1.0000f, 0.8900f, 0.8448f, 0.9396f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9997f, 0.9998f, 0.9353f, 1.0000f, 0.8003f, 0.9309f, 0.9263f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9847f, 0.9947f, 0.9934f, 1.0000f, 0.6938f, 0.9190f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9524f, 0.9832f, 0.8817f, 1.0000f, 0.8688f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9071f, 0.8978f, 0.9687f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8550f, 0.9653f, 0.9437f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6102f, 0.8274f, 0.9710f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7165f, 0.9732f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9972f, 0.9798f, 0.8578f, 1.0000f, 0.6329f, 0.7315f, 0.9741f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9992f, 0.9728f, 0.9214f, 1.0000f, 0.7342f, 0.8040f, 0.9607f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9597f, 0.7658f, 0.8701f, 1.0000f, 0.7545f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9443f, 0.9518f, 0.8675f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4210f, 0.8187f, 0.9020f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7070f, 0.9558f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6051f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8634f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9815f, 0.9908f, 0.9724f, 1.0000f, 0.3492f, 0.6194f, 0.9147f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9536f, 0.9766f, 0.7984f, 1.0000f, 0.4885f, 0.8989f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6619f, 0.8291f, 0.9317f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 0.7867f, 0.8999f, 0.9719f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.5999f, 0.8792f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9999f, 0.9996f, + 1.0000f, 0.7786f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9994f, 0.9924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9754f, 0.9879f, 0.9361f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9838f, 0.8477f, + 1.0000f, 0.8661f, 0.9324f, 0.9638f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 1.0000f, + 1.0000f, 0.9828f, 0.9110f, 0.9041f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9995f, + 1.0000f, 0.7102f, 0.9658f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9987f, 0.9906f, + 1.0000f, 0.8506f, 0.9678f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9989f, 0.9031f, + 1.0000f, 0.6657f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9868f, 0.9922f, 0.9871f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9581f, 0.9887f, 0.8521f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9801f, 0.7907f, 0.8059f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9475f, 0.9129f, 0.8223f, + 1.0000f, 1.0000f, 0.9919f, 0.9978f, 1.0000f, 0.9570f, 0.8621f, 0.7397f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9954f, 0.9986f, 0.9962f, 1.0000f, 0.9382f, 0.7497f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9961f, 0.9663f, 0.9618f, 1.0000f, 0.9231f, 0.9706f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9862f, 0.9456f, 0.5672f, 1.0000f, 0.6285f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9794f, 0.8779f, 0.5894f, 1.0000f, 0.8934f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8923f, 0.6971f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9715f, 0.8866f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9643f, 0.9633f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9930f, 0.9873f, 1.0000f, 0.9494f, 0.7636f, 0.9971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9805f, 0.9850f, 0.9424f, 1.0000f, 0.9368f, 0.7568f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9856f, 0.8078f, 0.3407f, 1.0000f, 0.9417f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9091f, 0.7226f, 0.5382f, 1.0000f, 0.7521f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9279f, 0.4139f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7926f, 0.7005f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9469f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8727f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9901f, 0.9701f, 0.9294f, 1.0000f, 0.9389f, 0.7807f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9819f, 0.9302f, 0.6503f, 1.0000f, 0.8945f, 0.9915f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, + 1.0000f, 0.9488f, 0.6870f, 0.7473f, 1.0000f, 0.9750f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9994f, + 1.0000f, 0.8766f, 0.2451f, 1.0000f, 1.0000f, 0.9945f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9990f, + 1.0000f, 0.8714f, 0.9120f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9932f, 0.9966f, + 1.0000f, 0.4351f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9997f, 0.9993f, + 1.0000f, 0.9623f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9844f, 0.9890f, + 1.0000f, 0.9876f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9745f, 0.9903f, 0.9822f, + 1.0000f, 0.9898f, 0.9506f, 0.7887f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9955f, + 1.0000f, 0.9586f, 0.9081f, 0.6801f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9893f, + 1.0000f, 0.9591f, 0.4950f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9958f, + 1.0000f, 0.8607f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9865f, 0.9911f, + 1.0000f, 0.9339f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.9770f, 0.9564f, + 1.0000f, 0.6418f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9808f, 0.9762f, 0.6581f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9917f, 0.9683f, 0.9101f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9835f, 0.9612f, 0.9553f, + 1.0000f, 0.9963f, 0.8340f, 0.5442f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9825f, 0.8205f, 0.8257f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3577f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7744f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6904f, 0.3984f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4690f, 0.9790f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4557f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9991f, 0.9973f, + 1.0000f, 0.8433f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9999f, 0.9993f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 1.0000f, 0.9859f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9410f, 0.7827f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 0.9239f, 0.9463f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9692f, 0.8878f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8889f, 0.9928f, 1.0000f, + 1.0000f, 0.9975f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9841f, 0.9974f, 0.9913f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9786f, 0.9984f, 0.8492f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9255f, 0.4755f, 0.9164f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8535f, 0.7196f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6766f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9500f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_10x6[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8941f, 0.9467f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8379f, 0.9490f, + 1.0000f, 1.0000f, 1.0000f, 0.9941f, 1.0000f, 0.8989f, 0.9438f, 0.9693f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8151f, 0.9709f, + 1.0000f, 1.0000f, 0.9775f, 0.9933f, 1.0000f, 0.9080f, 0.8642f, 0.4327f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9163f, 0.8850f, + 1.0000f, 1.0000f, 0.9867f, 0.9931f, 1.0000f, 0.8135f, 0.7809f, 0.4020f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9368f, 0.9362f, 0.9130f, + 1.0000f, 1.0000f, 0.9517f, 0.9765f, 1.0000f, 0.8240f, 0.4618f, 0.4733f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9355f, 0.8951f, 0.6674f, + 1.0000f, 0.9665f, 0.9847f, 0.9792f, 1.0000f, 0.7557f, 0.1083f, 0.7349f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8352f, 0.8595f, 0.5053f, + 1.0000f, 1.0000f, 0.9245f, 0.9223f, 1.0000f, 0.7599f, 0.0550f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8419f, 0.5920f, 0.1947f, + 1.0000f, 0.9147f, 0.8338f, 0.6978f, 1.0000f, 0.3094f, 0.3954f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7977f, 0.4386f, 0.5523f, + 1.0000f, 1.0000f, 1.0000f, 0.9862f, 1.0000f, 1.0000f, 0.8406f, 0.8392f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9876f, 0.9902f, 1.0000f, 0.8509f, 0.9097f, 0.8458f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9568f, 0.9839f, 1.0000f, 0.8269f, 0.7827f, 0.4145f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9578f, 0.9614f, 0.8471f, 1.0000f, 0.7736f, 0.3680f, 0.4444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8764f, 0.8742f, 1.0000f, 0.7679f, 0.1488f, 0.6830f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8687f, 0.7698f, 0.5151f, 1.0000f, 0.5568f, 0.2373f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9266f, 0.7945f, 0.5747f, 1.0000f, 0.5339f, 0.2167f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7912f, 0.6891f, 0.2565f, 1.0000f, 0.0936f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9528f, 0.9936f, 0.7844f, 1.0000f, 0.5293f, 0.7536f, 0.2275f, 1.0000f, 1.0000f, 1.0000f, 0.7063f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9824f, 0.9957f, 0.6204f, 0.5386f, 0.5432f, 0.5703f, 0.1226f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9017f, 0.8497f, 0.7324f, 0.6769f, 0.5792f, 0.3172f, 0.1722f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9062f, 0.9230f, 0.8432f, 0.3542f, 0.7035f, 0.5003f, 0.6920f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9315f, 0.8283f, 0.3817f, 0.7274f, 0.6044f, 0.1606f, 1.0000f, 0.5878f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8041f, 0.7660f, 0.3471f, 0.0336f, 0.4082f, 0.6706f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, + 1.0000f, 0.8891f, 0.4790f, 0.1362f, 0.5199f, 0.6243f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9950f, + 1.0000f, 0.7755f, 0.2752f, 0.4902f, 0.1835f, 0.0761f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9939f, 0.9989f, + 1.0000f, 1.0000f, 0.9450f, 0.9724f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9381f, 0.9750f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8709f, 0.8970f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, + 1.0000f, 0.8365f, 0.9294f, 0.4267f, 0.6125f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, + 1.0000f, 0.9122f, 0.7199f, 0.3248f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9681f, 0.9942f, + 1.0000f, 0.7299f, 0.3886f, 0.6003f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9919f, 0.9975f, + 1.0000f, 0.8057f, 0.2472f, 0.4502f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9632f, 0.9869f, + 1.0000f, 0.6575f, 0.2842f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9661f, 0.9786f, 0.9252f, + 1.0000f, 0.9972f, 0.9986f, 0.9974f, 1.0000f, 0.9106f, 0.8653f, 0.9601f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9677f, 0.9697f, 0.9088f, + 1.0000f, 0.9996f, 0.9996f, 0.9419f, 1.0000f, 0.8181f, 0.9501f, 0.9685f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9689f, 0.9507f, 0.6541f, + 1.0000f, 0.9779f, 0.9954f, 0.9849f, 1.0000f, 0.7172f, 0.9201f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7468f, 0.7249f, 0.9208f, + 1.0000f, 0.9259f, 0.9815f, 0.8484f, 1.0000f, 0.8829f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7862f, 0.8775f, 0.9799f, + 1.0000f, 0.9114f, 0.9139f, 0.9743f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6506f, 0.9705f, 1.0000f, + 1.0000f, 0.8618f, 0.9739f, 0.9444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8166f, 1.0000f, 1.0000f, + 1.0000f, 0.5613f, 0.9193f, 0.9563f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7619f, 0.9890f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9980f, 0.9818f, 0.8607f, 1.0000f, 0.6471f, 0.7444f, 0.9645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9991f, 0.9736f, 0.9321f, 1.0000f, 0.7224f, 0.8254f, 0.9720f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9479f, 0.7491f, 0.8311f, 1.0000f, 0.7928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9186f, 0.9280f, 0.8445f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4206f, 0.8676f, 0.9301f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7397f, 0.9809f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6949f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8009f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9864f, 0.9881f, 0.9747f, 1.0000f, 0.3611f, 0.6164f, 0.9155f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9636f, 0.9758f, 0.8025f, 1.0000f, 0.4676f, 0.8839f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6359f, 0.8088f, 0.9335f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, + 1.0000f, 0.7718f, 0.8931f, 0.9673f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9999f, + 1.0000f, 0.6642f, 0.9071f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9998f, 0.9996f, + 1.0000f, 0.8120f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9998f, 0.9926f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9963f, 0.9754f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9955f, 0.9796f, + 1.0000f, 0.8797f, 0.9400f, 0.9619f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 1.0000f, + 1.0000f, 0.9812f, 0.9216f, 0.9170f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9997f, + 1.0000f, 0.7007f, 0.9653f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9976f, 0.9649f, + 1.0000f, 0.8583f, 0.9554f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9969f, 0.8731f, + 1.0000f, 0.7090f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9859f, 0.9923f, 0.9914f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9549f, 0.9896f, 0.8786f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9802f, 0.8522f, 0.8818f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9713f, 0.9582f, 0.9407f, + 1.0000f, 1.0000f, 0.9885f, 0.9894f, 1.0000f, 0.9761f, 0.9008f, 0.7792f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9806f, 0.9640f, 0.9878f, + 1.0000f, 0.9986f, 0.9953f, 0.9995f, 1.0000f, 0.9610f, 0.8104f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9833f, 0.9830f, 0.9237f, + 1.0000f, 0.9982f, 0.9308f, 0.9432f, 1.0000f, 0.9461f, 0.9728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9904f, 0.9539f, 0.9944f, + 1.0000f, 0.9605f, 0.9596f, 0.3748f, 1.0000f, 0.6609f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9821f, 0.8860f, 1.0000f, + 1.0000f, 0.9857f, 0.8807f, 0.4560f, 1.0000f, 0.9026f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9425f, 0.9929f, 1.0000f, + 1.0000f, 0.9035f, 0.6435f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9394f, 1.0000f, 1.0000f, + 1.0000f, 0.9836f, 0.6861f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9732f, 1.0000f, 1.0000f, + 1.0000f, 0.8961f, 0.8559f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9883f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9912f, 0.9906f, 1.0000f, 0.9669f, 0.8225f, 0.9989f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9717f, 0.9947f, 0.9388f, 1.0000f, 0.9473f, 0.8210f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9841f, 0.7961f, 0.2929f, 1.0000f, 0.9484f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8881f, 0.7118f, 0.4846f, 1.0000f, 0.7640f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9178f, 0.3324f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7578f, 0.6321f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9273f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6397f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9967f, 0.9827f, 0.9533f, 1.0000f, 0.9455f, 0.7878f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9844f, 0.9558f, 0.6800f, 1.0000f, 0.9044f, 0.9921f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, + 1.0000f, 0.9623f, 0.6738f, 0.7513f, 1.0000f, 0.9701f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9999f, + 1.0000f, 0.8921f, 0.2659f, 1.0000f, 1.0000f, 0.9928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9959f, 0.9978f, + 1.0000f, 0.8698f, 0.8325f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9887f, 0.9979f, + 1.0000f, 0.3399f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9980f, 0.9999f, + 1.0000f, 0.8911f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9918f, 0.9988f, + 1.0000f, 0.9348f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9892f, 0.9958f, 0.9910f, + 1.0000f, 0.9852f, 0.9328f, 0.8534f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 0.9992f, + 1.0000f, 0.9544f, 0.9342f, 0.7421f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.9871f, + 1.0000f, 0.9587f, 0.4953f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9900f, 0.9934f, + 1.0000f, 0.8571f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9854f, 0.9925f, 0.9874f, + 1.0000f, 0.9053f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9496f, 0.9768f, + 1.0000f, 0.5246f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9657f, 0.9573f, 0.5962f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 0.9627f, 0.7895f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9772f, 0.8998f, 0.8980f, + 1.0000f, 0.9966f, 0.8547f, 0.6085f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8753f, 1.0000f, 1.0000f, + 1.0000f, 0.9916f, 0.7993f, 0.8630f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9523f, 1.0000f, 1.0000f, + 1.0000f, 0.2057f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7145f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7373f, 0.5103f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5835f, 0.9782f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5478f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9990f, + 1.0000f, 0.8720f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, 0.9961f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9997f, 0.9984f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.9999f, 0.9789f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9592f, 0.8072f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9413f, 0.9512f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9375f, 0.8871f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8195f, 0.9988f, 1.0000f, + 1.0000f, 0.9985f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9898f, 0.9993f, 0.9951f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9908f, 0.9993f, 0.8297f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8665f, 0.3015f, 0.8901f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7773f, 0.5658f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6282f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9287f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_10x8[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9515f, 0.9479f, 1.0000f, 1.0000f, 0.8697f, 0.8771f, 1.0000f, 1.0000f, 0.9852f, 0.9958f, + 1.0000f, 1.0000f, 1.0000f, 0.9911f, 1.0000f, 0.9611f, 0.9295f, 0.9716f, 1.0000f, 0.8951f, 0.9092f, 0.9403f, 1.0000f, 1.0000f, 0.9972f, 0.9990f, + 1.0000f, 1.0000f, 0.9844f, 0.9969f, 1.0000f, 0.9664f, 0.9466f, 0.6276f, 1.0000f, 0.9493f, 0.9133f, 0.7285f, 1.0000f, 1.0000f, 0.9671f, 0.9099f, + 1.0000f, 1.0000f, 0.9965f, 0.9962f, 1.0000f, 0.9506f, 0.8726f, 0.6061f, 1.0000f, 0.8687f, 0.8894f, 0.5709f, 1.0000f, 0.9763f, 0.9710f, 0.9254f, + 1.0000f, 1.0000f, 0.9651f, 0.9654f, 1.0000f, 0.9339f, 0.6408f, 0.6024f, 1.0000f, 0.8967f, 0.7477f, 0.4102f, 1.0000f, 0.9697f, 0.9447f, 0.6344f, + 1.0000f, 0.9838f, 0.9908f, 0.9749f, 1.0000f, 0.8789f, 0.2292f, 0.8488f, 1.0000f, 0.9085f, 0.4279f, 0.9377f, 1.0000f, 0.9323f, 0.8919f, 0.5870f, + 1.0000f, 1.0000f, 0.9489f, 0.9408f, 1.0000f, 0.8587f, 0.0655f, 1.0000f, 1.0000f, 0.8077f, 0.1170f, 1.0000f, 1.0000f, 0.9272f, 0.5831f, 0.2550f, + 1.0000f, 0.9497f, 0.8762f, 0.6703f, 1.0000f, 0.5236f, 0.5095f, 1.0000f, 1.0000f, 0.6501f, 0.6867f, 1.0000f, 1.0000f, 0.8943f, 0.3798f, 0.6470f, + 1.0000f, 1.0000f, 1.0000f, 0.9858f, 1.0000f, 1.0000f, 0.9397f, 0.8885f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9925f, 0.9871f, + 1.0000f, 1.0000f, 0.9879f, 0.9977f, 1.0000f, 0.9532f, 0.9427f, 0.8477f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9890f, 0.9784f, + 1.0000f, 1.0000f, 0.9647f, 0.9866f, 1.0000f, 0.9192f, 0.8807f, 0.5458f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9248f, 0.9260f, + 1.0000f, 0.9792f, 0.9856f, 0.8618f, 1.0000f, 0.9113f, 0.5750f, 0.5909f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9502f, 0.9644f, 0.6136f, + 1.0000f, 1.0000f, 0.9355f, 0.8735f, 1.0000f, 0.8911f, 0.3399f, 0.7919f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9722f, 0.8576f, 0.4565f, + 1.0000f, 0.9328f, 0.8179f, 0.5142f, 1.0000f, 0.7394f, 0.3860f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8466f, 0.5281f, 0.6098f, + 1.0000f, 0.9626f, 0.8454f, 0.5500f, 1.0000f, 0.7352f, 0.3026f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9140f, 0.3179f, 0.4941f, + 1.0000f, 0.8975f, 0.7239f, 0.3255f, 1.0000f, 0.2379f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7670f, 0.2871f, 1.0000f, + 1.0000f, 1.0000f, 0.9746f, 0.9918f, 0.9035f, 1.0000f, 0.7019f, 0.8062f, 0.1283f, 1.0000f, 1.0000f, 1.0000f, 0.5326f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9875f, 0.9948f, 0.6787f, 0.6618f, 0.6439f, 0.5627f, 0.1819f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9688f, 0.8716f, 0.8311f, 0.8016f, 0.7216f, 0.3922f, 0.1716f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9731f, 0.9553f, 0.8834f, 0.4337f, 0.8780f, 0.5948f, 0.6994f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9528f, 0.9160f, 0.4620f, 0.8407f, 0.7069f, 0.3103f, 1.0000f, 0.4162f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9078f, 0.8207f, 0.4220f, 0.0000f, 0.6731f, 0.6892f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9936f, + 1.0000f, 0.8998f, 0.5542f, 0.2015f, 0.7779f, 0.6841f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, + 1.0000f, 0.8648f, 0.2948f, 0.5044f, 0.1610f, 0.1052f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9991f, + 1.0000f, 1.0000f, 0.9725f, 0.9787f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9771f, 0.9577f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9371f, 0.9361f, 0.0921f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, + 1.0000f, 0.9585f, 0.9737f, 0.6207f, 0.6171f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9898f, + 1.0000f, 0.9704f, 0.8544f, 0.4837f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9903f, 0.9991f, + 1.0000f, 0.8565f, 0.4784f, 0.7118f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9942f, 0.9949f, + 1.0000f, 0.9020f, 0.3470f, 0.5415f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9850f, 0.9932f, + 1.0000f, 0.7968f, 0.4509f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9896f, 0.9909f, 0.9071f, + 1.0000f, 0.9987f, 0.9993f, 0.9974f, 1.0000f, 0.9027f, 0.8668f, 0.9565f, 1.0000f, 0.8860f, 0.7436f, 0.7576f, 1.0000f, 0.9959f, 0.9947f, 0.9829f, + 1.0000f, 0.9997f, 0.9999f, 0.9545f, 1.0000f, 0.8431f, 0.9413f, 0.9811f, 1.0000f, 0.8107f, 0.7537f, 0.7633f, 1.0000f, 0.9864f, 0.9929f, 0.8744f, + 1.0000f, 0.9604f, 0.9867f, 0.9827f, 1.0000f, 0.8032f, 0.9470f, 1.0000f, 1.0000f, 0.6560f, 0.9678f, 1.0000f, 1.0000f, 0.7652f, 0.8877f, 0.9774f, + 1.0000f, 0.9064f, 0.9755f, 0.8359f, 1.0000f, 0.9127f, 1.0000f, 1.0000f, 1.0000f, 0.7832f, 1.0000f, 1.0000f, 1.0000f, 0.8607f, 0.9596f, 0.9880f, + 1.0000f, 0.8658f, 0.8816f, 0.9622f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7814f, 0.9510f, 1.0000f, + 1.0000f, 0.8273f, 0.9713f, 0.9461f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9289f, 1.0000f, 1.0000f, + 1.0000f, 0.5189f, 0.9179f, 0.9728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8193f, 0.9719f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9982f, 0.9834f, 0.8851f, 1.0000f, 0.6531f, 0.7498f, 0.9278f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9317f, 0.9456f, 0.9437f, + 1.0000f, 0.9985f, 0.9707f, 0.9283f, 1.0000f, 0.7518f, 0.8165f, 0.9825f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9877f, 0.9056f, 0.8959f, + 1.0000f, 0.9418f, 0.7743f, 0.8522f, 1.0000f, 0.8511f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7143f, 0.9049f, 1.0000f, + 1.0000f, 0.9366f, 0.9387f, 0.9266f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8335f, 0.9782f, 1.0000f, + 1.0000f, 0.3329f, 0.7984f, 0.9350f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8868f, 1.0000f, 1.0000f, + 1.0000f, 0.7191f, 0.9212f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7761f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7952f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9891f, 0.9807f, 0.9740f, 0.8047f, 0.3669f, 0.5585f, 0.9224f, 0.0517f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9619f, 0.9789f, 0.8323f, 0.4043f, 0.4452f, 0.8419f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7093f, 0.8707f, 0.9700f, 0.8500f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.8260f, 0.9186f, 0.9823f, 0.0191f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.7167f, 0.9005f, 1.0000f, 0.6814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, 0.9975f, + 1.0000f, 0.8628f, 1.0000f, 1.0000f, 0.1918f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9997f, 0.9752f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0789f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9983f, 0.9640f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9927f, 0.9818f, + 1.0000f, 0.9106f, 0.9475f, 0.9573f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 1.0000f, + 1.0000f, 0.9884f, 0.9334f, 0.9382f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 0.7689f, 0.9684f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9964f, 0.9536f, + 1.0000f, 0.8935f, 0.9779f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9966f, 0.9943f, 0.8122f, + 1.0000f, 0.7797f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9588f, 0.9848f, 0.9694f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9218f, 0.9681f, 0.8247f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9557f, 0.8371f, 0.8983f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9561f, 0.9600f, 0.9312f, + 1.0000f, 1.0000f, 0.9963f, 0.9995f, 1.0000f, 0.9901f, 0.8753f, 0.8234f, 1.0000f, 0.9941f, 0.9766f, 0.8843f, 1.0000f, 0.9967f, 0.9893f, 0.9809f, + 1.0000f, 0.9995f, 0.9989f, 0.9980f, 1.0000f, 0.9630f, 0.8220f, 1.0000f, 1.0000f, 0.9913f, 0.9120f, 1.0000f, 1.0000f, 0.9920f, 0.9944f, 0.8298f, + 1.0000f, 0.9973f, 0.9983f, 0.9523f, 1.0000f, 0.9840f, 0.9804f, 1.0000f, 1.0000f, 0.9873f, 0.9888f, 1.0000f, 1.0000f, 0.9970f, 0.8555f, 0.9661f, + 1.0000f, 0.9935f, 0.9820f, 0.4675f, 1.0000f, 0.7308f, 1.0000f, 1.0000f, 1.0000f, 0.9344f, 1.0000f, 1.0000f, 1.0000f, 0.9836f, 0.6918f, 1.0000f, + 1.0000f, 0.9906f, 0.9013f, 0.2200f, 1.0000f, 0.9166f, 1.0000f, 1.0000f, 1.0000f, 0.9882f, 1.0000f, 1.0000f, 1.0000f, 0.9675f, 0.8902f, 1.0000f, + 1.0000f, 0.9423f, 0.5371f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6590f, 1.0000f, 1.0000f, + 1.0000f, 0.9842f, 0.4889f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9236f, 1.0000f, 1.0000f, + 1.0000f, 0.9042f, 0.5986f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7867f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9979f, 0.9956f, 1.0000f, 0.9895f, 0.8136f, 0.9760f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9869f, 0.9933f, 0.9242f, + 1.0000f, 0.9965f, 0.9984f, 0.9569f, 1.0000f, 0.9549f, 0.7884f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9928f, 0.9581f, 0.8383f, + 1.0000f, 0.9432f, 0.9153f, 0.3536f, 1.0000f, 0.9776f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.7707f, 1.0000f, + 1.0000f, 0.9633f, 0.7557f, 0.4993f, 1.0000f, 0.7614f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9484f, 1.0000f, 1.0000f, + 1.0000f, 0.9886f, 0.2465f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9658f, 1.0000f, 1.0000f, + 1.0000f, 0.8347f, 0.3603f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6969f, 1.0000f, 1.0000f, + 1.0000f, 0.9607f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2712f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9757f, 0.9905f, 0.9637f, 0.7902f, 0.9592f, 0.6376f, 1.0000f, 0.6241f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9900f, 0.9831f, 0.7849f, 0.1502f, 0.8443f, 0.9768f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 0.9854f, 0.7457f, 0.8597f, 0.5791f, 0.9147f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9997f, + 1.0000f, 0.9519f, 0.3733f, 1.0000f, 0.2792f, 0.9916f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 0.9998f, + 1.0000f, 0.9691f, 0.6943f, 1.0000f, 0.0378f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.9999f, + 1.0000f, 0.3982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9985f, 1.0000f, + 1.0000f, 0.8798f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, 0.9968f, + 1.0000f, 0.6759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9799f, 0.9975f, 0.9937f, + 1.0000f, 0.9971f, 0.9734f, 0.8927f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9917f, + 1.0000f, 0.9860f, 0.9300f, 0.8151f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, 0.9921f, + 1.0000f, 0.9802f, 0.6310f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, 0.9996f, + 1.0000f, 0.8825f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9986f, 0.9797f, + 1.0000f, 0.9451f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9931f, 0.9668f, + 1.0000f, 0.4730f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9952f, 0.9743f, 0.4395f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9615f, 0.6647f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9794f, 0.8286f, 0.7373f, + 1.0000f, 0.9981f, 0.9306f, 0.7595f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7725f, 1.0000f, 1.0000f, + 1.0000f, 0.9950f, 0.9230f, 0.9816f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9846f, 1.0000f, 1.0000f, + 1.0000f, 0.1394f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6675f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8395f, 0.7330f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7263f, 0.9914f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7044f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9998f, 0.9990f, + 1.0000f, 0.8990f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9814f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9923f, 0.9998f, 0.9988f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.9994f, 0.9540f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9392f, 0.8000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9442f, 0.9205f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9173f, 0.8638f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8092f, 0.9994f, 1.0000f, + 1.0000f, 0.9976f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 0.9995f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9862f, 0.9987f, 0.9199f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8678f, 0.2109f, 0.8533f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7936f, 0.5668f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2632f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7415f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_10x10[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9686f, 0.9633f, 1.0000f, 1.0000f, 0.9876f, 0.9703f, 1.0000f, 1.0000f, 0.9951f, 0.9984f, + 1.0000f, 1.0000f, 1.0000f, 0.9987f, 1.0000f, 0.9597f, 0.9643f, 0.9819f, 1.0000f, 0.9912f, 0.9804f, 0.9869f, 1.0000f, 1.0000f, 0.9981f, 0.9988f, + 1.0000f, 1.0000f, 0.9866f, 0.9992f, 1.0000f, 0.9719f, 0.9513f, 0.6842f, 1.0000f, 0.9677f, 0.9562f, 0.6732f, 1.0000f, 1.0000f, 0.9855f, 0.8914f, + 1.0000f, 1.0000f, 0.9976f, 0.9965f, 1.0000f, 0.9489f, 0.9125f, 0.6280f, 1.0000f, 0.9555f, 0.9218f, 0.5776f, 1.0000f, 0.9848f, 0.9797f, 0.9019f, + 1.0000f, 1.0000f, 0.9722f, 0.9737f, 1.0000f, 0.9587f, 0.7179f, 0.6996f, 1.0000f, 0.9485f, 0.6921f, 0.6084f, 1.0000f, 0.9680f, 0.9464f, 0.5482f, + 1.0000f, 0.9928f, 0.9888f, 0.9630f, 1.0000f, 0.9316f, 0.3859f, 0.9151f, 1.0000f, 0.9447f, 0.3221f, 0.8991f, 1.0000f, 0.9326f, 0.8735f, 0.5210f, + 1.0000f, 1.0000f, 0.9365f, 0.9047f, 1.0000f, 0.8590f, 0.1201f, 1.0000f, 1.0000f, 0.8610f, 0.0462f, 1.0000f, 1.0000f, 0.9540f, 0.5048f, 0.2354f, + 1.0000f, 0.9551f, 0.8452f, 0.5669f, 1.0000f, 0.6051f, 0.6704f, 1.0000f, 1.0000f, 0.5983f, 0.6150f, 1.0000f, 1.0000f, 0.8866f, 0.3154f, 0.5406f, + 1.0000f, 1.0000f, 1.0000f, 0.9933f, 1.0000f, 1.0000f, 0.9700f, 0.8930f, 1.0000f, 1.0000f, 0.9765f, 0.9073f, 1.0000f, 1.0000f, 0.9902f, 0.9934f, + 1.0000f, 1.0000f, 0.9981f, 0.9982f, 1.0000f, 0.9750f, 0.9306f, 0.8620f, 1.0000f, 0.9620f, 0.9649f, 0.9113f, 1.0000f, 1.0000f, 0.9873f, 0.9878f, + 1.0000f, 1.0000f, 0.9914f, 0.9909f, 1.0000f, 0.9438f, 0.9067f, 0.5915f, 1.0000f, 0.9614f, 0.9212f, 0.6344f, 1.0000f, 1.0000f, 0.9509f, 0.9341f, + 1.0000f, 0.9852f, 0.9853f, 0.8669f, 1.0000f, 0.9356f, 0.5949f, 0.6407f, 1.0000f, 0.9346f, 0.6376f, 0.4882f, 1.0000f, 0.9729f, 0.9817f, 0.6647f, + 1.0000f, 1.0000f, 0.9573f, 0.9224f, 1.0000f, 0.9274f, 0.4705f, 0.8707f, 1.0000f, 0.9403f, 0.4174f, 0.8396f, 1.0000f, 0.9793f, 0.8539f, 0.5595f, + 1.0000f, 0.9601f, 0.8529f, 0.5705f, 1.0000f, 0.8121f, 0.5007f, 1.0000f, 1.0000f, 0.8227f, 0.3286f, 1.0000f, 1.0000f, 0.9005f, 0.4838f, 0.7513f, + 1.0000f, 0.9580f, 0.8753f, 0.4567f, 1.0000f, 0.7422f, 0.4275f, 1.0000f, 1.0000f, 0.8005f, 0.2434f, 1.0000f, 1.0000f, 0.9144f, 0.3582f, 0.6117f, + 1.0000f, 0.8841f, 0.6788f, 0.2513f, 1.0000f, 0.3348f, 1.0000f, 1.0000f, 1.0000f, 0.2949f, 1.0000f, 1.0000f, 1.0000f, 0.8093f, 0.4613f, 1.0000f, + 1.0000f, 1.0000f, 0.9864f, 0.9965f, 0.8998f, 1.0000f, 0.7243f, 0.8107f, 0.0803f, 1.0000f, 0.7755f, 0.8807f, 0.4324f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9950f, 0.9978f, 0.6895f, 0.7113f, 0.7020f, 0.5330f, 0.1295f, 0.7285f, 0.8149f, 0.7201f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9716f, 0.9012f, 0.8314f, 0.8162f, 0.7403f, 0.4018f, 0.1665f, 0.8953f, 0.7566f, 0.3912f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9826f, 0.9683f, 0.9087f, 0.4518f, 0.8983f, 0.5740f, 0.7068f, 1.0000f, 0.8882f, 0.6815f, 0.6676f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9697f, 0.9468f, 0.5558f, 0.8507f, 0.7495f, 0.3965f, 1.0000f, 0.4659f, 0.8350f, 0.2666f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9434f, 0.8815f, 0.5520f, 0.0320f, 0.7157f, 0.7929f, 1.0000f, 1.0000f, 0.7477f, 0.7804f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, + 1.0000f, 0.9501f, 0.5129f, 0.2591f, 0.7670f, 0.6869f, 1.0000f, 1.0000f, 1.0000f, 0.7601f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 0.9157f, 0.3086f, 0.5089f, 0.2273f, 0.1008f, 1.0000f, 1.0000f, 1.0000f, 0.1575f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9998f, + 1.0000f, 1.0000f, 0.9782f, 0.9947f, 0.3018f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9861f, 0.9815f, 0.6439f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9533f, 0.9300f, 0.2022f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, + 1.0000f, 0.9694f, 0.9476f, 0.6589f, 0.6500f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, + 1.0000f, 0.9832f, 0.8922f, 0.5632f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9925f, 0.9988f, + 1.0000f, 0.9033f, 0.5170f, 0.7771f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9944f, + 1.0000f, 0.8824f, 0.3804f, 0.6469f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9953f, 0.9770f, + 1.0000f, 0.8290f, 0.5291f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9921f, 0.8798f, + 1.0000f, 0.9995f, 0.9992f, 0.9980f, 1.0000f, 0.9230f, 0.8849f, 0.9590f, 1.0000f, 0.9375f, 0.8938f, 0.9370f, 1.0000f, 0.9952f, 0.9968f, 0.9891f, + 1.0000f, 0.9998f, 0.9999f, 0.9623f, 1.0000f, 0.8640f, 0.9493f, 0.9881f, 1.0000f, 0.9163f, 0.9521f, 0.9779f, 1.0000f, 0.9857f, 0.9874f, 0.8890f, + 1.0000f, 0.9529f, 0.9871f, 0.9802f, 1.0000f, 0.8078f, 0.9544f, 1.0000f, 1.0000f, 0.8049f, 0.9442f, 1.0000f, 1.0000f, 0.7091f, 0.8906f, 0.9671f, + 1.0000f, 0.9206f, 0.9652f, 0.8302f, 1.0000f, 0.9175f, 1.0000f, 1.0000f, 1.0000f, 0.9040f, 1.0000f, 1.0000f, 1.0000f, 0.8408f, 0.9336f, 0.9905f, + 1.0000f, 0.9026f, 0.8833f, 0.9784f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7531f, 0.9407f, 1.0000f, + 1.0000f, 0.8580f, 0.9611f, 0.9774f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8961f, 1.0000f, 1.0000f, + 1.0000f, 0.3694f, 0.8697f, 0.9674f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7548f, 0.9384f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9986f, 0.9900f, 0.8968f, 1.0000f, 0.7044f, 0.7787f, 0.9517f, 1.0000f, 0.7975f, 0.7738f, 0.9060f, 1.0000f, 0.9295f, 0.9662f, 0.9760f, + 1.0000f, 0.9985f, 0.9788f, 0.9351f, 1.0000f, 0.7459f, 0.8189f, 0.9899f, 1.0000f, 0.8385f, 0.8560f, 0.9927f, 1.0000f, 0.9859f, 0.9451f, 0.9813f, + 1.0000f, 0.9398f, 0.7653f, 0.8486f, 1.0000f, 0.8762f, 1.0000f, 1.0000f, 1.0000f, 0.8550f, 1.0000f, 1.0000f, 1.0000f, 0.7990f, 0.9862f, 1.0000f, + 1.0000f, 0.9188f, 0.9268f, 0.9119f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9235f, 0.9923f, 1.0000f, + 1.0000f, 0.3638f, 0.8497f, 0.9668f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9194f, 1.0000f, 1.0000f, + 1.0000f, 0.7721f, 0.9481f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7346f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7704f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9916f, 0.9926f, 0.9742f, 0.8201f, 0.3525f, 0.5368f, 0.9252f, 0.1389f, 0.6017f, 0.5846f, 0.9800f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9692f, 0.9834f, 0.8570f, 0.4373f, 0.4071f, 0.8277f, 1.0000f, 1.0000f, 0.6312f, 0.8326f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7135f, 0.8858f, 0.9594f, 0.8362f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.8430f, 0.9389f, 0.9836f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, + 1.0000f, 0.8020f, 0.9460f, 1.0000f, 0.7306f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9995f, 0.9964f, + 1.0000f, 0.9285f, 1.0000f, 1.0000f, 0.2108f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9655f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0909f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9918f, 0.9200f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9830f, 0.9607f, + 1.0000f, 0.9290f, 0.9421f, 0.9604f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 0.9828f, 0.9246f, 0.9525f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.7851f, 0.9734f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9943f, 0.9505f, + 1.0000f, 0.9106f, 0.9840f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9922f, 0.7867f, + 1.0000f, 0.8945f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9636f, 0.9886f, 0.9732f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9132f, 0.9640f, 0.8441f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9472f, 0.7687f, 0.8373f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9321f, 0.9331f, 0.8976f, + 1.0000f, 1.0000f, 0.9970f, 0.9996f, 1.0000f, 0.9956f, 0.9182f, 0.8475f, 1.0000f, 0.9569f, 0.9838f, 0.8688f, 1.0000f, 0.9911f, 0.9938f, 0.9884f, + 1.0000f, 1.0000f, 0.9954f, 0.9995f, 1.0000f, 0.9896f, 0.8725f, 1.0000f, 1.0000f, 0.9972f, 0.9258f, 1.0000f, 1.0000f, 0.9915f, 0.9963f, 0.8176f, + 1.0000f, 1.0000f, 0.9985f, 0.9393f, 1.0000f, 0.9850f, 0.9937f, 1.0000f, 1.0000f, 0.9822f, 0.9705f, 1.0000f, 1.0000f, 0.9993f, 0.7636f, 0.8899f, + 1.0000f, 0.9903f, 0.9844f, 0.3467f, 1.0000f, 0.7883f, 1.0000f, 1.0000f, 1.0000f, 0.8252f, 1.0000f, 1.0000f, 1.0000f, 0.9617f, 0.4750f, 1.0000f, + 1.0000f, 0.9984f, 0.9053f, 0.2192f, 1.0000f, 0.9093f, 1.0000f, 1.0000f, 1.0000f, 0.9497f, 1.0000f, 1.0000f, 1.0000f, 0.9416f, 0.7365f, 1.0000f, + 1.0000f, 0.9811f, 0.4965f, 0.9930f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5251f, 1.0000f, 1.0000f, + 1.0000f, 0.9967f, 0.2879f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8716f, 1.0000f, 1.0000f, + 1.0000f, 0.8600f, 0.4470f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5880f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9974f, 0.9971f, 1.0000f, 0.9969f, 0.8630f, 0.9966f, 1.0000f, 0.9889f, 0.9241f, 0.9946f, 1.0000f, 0.9962f, 0.9767f, 0.8874f, + 1.0000f, 0.9973f, 0.9999f, 0.9762f, 1.0000f, 0.9689f, 0.8135f, 1.0000f, 1.0000f, 0.9868f, 0.8744f, 1.0000f, 1.0000f, 0.9936f, 0.9708f, 0.8064f, + 1.0000f, 0.9990f, 0.9138f, 0.3409f, 1.0000f, 0.9786f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, 1.0000f, 1.0000f, 1.0000f, 0.9957f, 0.6530f, 1.0000f, + 1.0000f, 0.9665f, 0.7584f, 0.6215f, 1.0000f, 0.7960f, 1.0000f, 1.0000f, 1.0000f, 0.8214f, 1.0000f, 1.0000f, 1.0000f, 0.9263f, 1.0000f, 1.0000f, + 1.0000f, 0.9932f, 0.2809f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9576f, 1.0000f, 1.0000f, + 1.0000f, 0.8789f, 0.4794f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4923f, 1.0000f, 1.0000f, + 1.0000f, 0.9727f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.1844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9894f, 0.9931f, 0.9646f, 0.8518f, 0.9740f, 0.6760f, 1.0000f, 0.3749f, 0.9755f, 0.8771f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9972f, 0.9806f, 0.8419f, 0.0162f, 0.8659f, 0.9745f, 1.0000f, 1.0000f, 0.9566f, 0.9892f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, + 1.0000f, 0.9955f, 0.7384f, 0.9080f, 0.7326f, 0.9169f, 1.0000f, 1.0000f, 1.0000f, 0.9791f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.9986f, + 1.0000f, 0.9714f, 0.4225f, 1.0000f, 0.1933f, 0.9795f, 1.0000f, 1.0000f, 1.0000f, 0.9809f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, + 1.0000f, 0.9757f, 0.7914f, 1.0000f, 0.1105f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 0.9997f, + 1.0000f, 0.5444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9977f, 0.9994f, 0.9940f, + 1.0000f, 0.8678f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.6618f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 1.0000f, 0.9897f, + 1.0000f, 0.9991f, 0.9658f, 0.9429f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 1.0000f, + 1.0000f, 0.9942f, 0.9425f, 0.8780f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9846f, + 1.0000f, 0.9939f, 0.6971f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9711f, + 1.0000f, 0.9455f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9724f, 0.9777f, + 1.0000f, 0.9752f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9883f, 0.9412f, + 1.0000f, 0.5811f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9982f, 0.9879f, 0.4421f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9536f, 0.4123f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9583f, 0.7820f, 0.6183f, + 1.0000f, 0.9994f, 0.9772f, 0.8035f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7264f, 1.0000f, 1.0000f, + 1.0000f, 0.9959f, 0.9627f, 0.9908f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9379f, 1.0000f, 1.0000f, + 1.0000f, 0.1755f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9100f, 0.8338f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 1.0000f, 1.0000f, + 1.0000f, 0.8265f, 0.9995f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7899f, 1.0000f, 1.0000f, 0.7619f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9747f, 1.0000f, 1.0000f, 0.0584f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, 0.9824f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0694f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9979f, 0.9990f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9842f, 1.0000f, 0.9311f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.9361f, 0.7836f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9919f, 0.9279f, 0.9548f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8649f, 0.7440f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7945f, 0.9959f, 1.0000f, + 1.0000f, 0.9941f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9961f, 1.0000f, 0.9960f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9990f, 0.9559f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8464f, 0.2739f, 0.8240f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7222f, 0.6248f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1483f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6559f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_10x12[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9716f, 0.9549f, 1.0000f, 1.0000f, 0.9881f, 0.9817f, 1.0000f, 1.0000f, 0.9984f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, 0.9617f, 0.9697f, 0.9825f, 1.0000f, 0.9916f, 0.9941f, 0.9689f, 1.0000f, 1.0000f, 0.9980f, 0.9967f, + 1.0000f, 1.0000f, 0.9940f, 0.9997f, 1.0000f, 0.9641f, 0.9573f, 0.7080f, 1.0000f, 0.9918f, 0.9662f, 0.6854f, 1.0000f, 1.0000f, 0.9815f, 0.8889f, + 1.0000f, 1.0000f, 0.9986f, 0.9932f, 1.0000f, 0.9604f, 0.8881f, 0.6661f, 1.0000f, 0.9456f, 0.9130f, 0.6171f, 1.0000f, 0.9600f, 0.9718f, 0.8502f, + 1.0000f, 1.0000f, 0.9899f, 0.9695f, 1.0000f, 0.9535f, 0.7366f, 0.7328f, 1.0000f, 0.9656f, 0.6923f, 0.6142f, 1.0000f, 0.9768f, 0.9189f, 0.4897f, + 1.0000f, 0.9924f, 0.9956f, 0.9650f, 1.0000f, 0.9349f, 0.4381f, 0.9238f, 1.0000f, 0.9344f, 0.3154f, 0.8961f, 1.0000f, 0.9270f, 0.8531f, 0.4604f, + 1.0000f, 1.0000f, 0.9731f, 0.8982f, 1.0000f, 0.9222f, 0.2598f, 1.0000f, 1.0000f, 0.8512f, 0.0780f, 1.0000f, 1.0000f, 0.9411f, 0.5059f, 0.1684f, + 1.0000f, 0.9853f, 0.8463f, 0.5987f, 1.0000f, 0.7036f, 0.7578f, 1.0000f, 1.0000f, 0.5618f, 0.5823f, 1.0000f, 1.0000f, 0.9093f, 0.2466f, 0.4938f, + 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.6877f, 1.0000f, 0.9506f, 0.9112f, 0.8695f, 1.0000f, 0.9909f, 0.9042f, 0.6611f, 1.0000f, 0.9971f, 0.9973f, + 1.0000f, 1.0000f, 0.9974f, 0.9945f, 0.8704f, 0.9827f, 0.9296f, 0.8642f, 0.7829f, 0.9553f, 0.9673f, 0.9380f, 0.4690f, 1.0000f, 0.9977f, 0.9878f, + 1.0000f, 1.0000f, 0.9936f, 0.9937f, 0.8453f, 0.9626f, 0.9036f, 0.6373f, 0.5889f, 0.9782f, 0.9155f, 0.6586f, 0.8293f, 1.0000f, 0.9483f, 0.9081f, + 1.0000f, 0.9770f, 0.9960f, 0.8975f, 0.7997f, 0.9502f, 0.6401f, 0.6686f, 0.2911f, 0.9460f, 0.6316f, 0.6259f, 1.0000f, 0.9647f, 0.9653f, 0.5176f, + 1.0000f, 1.0000f, 0.9539f, 0.9143f, 0.7943f, 0.9415f, 0.5253f, 0.8772f, 0.8247f, 0.9546f, 0.4239f, 0.8443f, 1.0000f, 0.9667f, 0.8114f, 0.3782f, + 1.0000f, 0.9475f, 0.8596f, 0.5652f, 0.2972f, 0.8259f, 0.5789f, 1.0000f, 1.0000f, 0.7983f, 0.4472f, 1.0000f, 1.0000f, 0.8624f, 0.3886f, 0.6508f, + 1.0000f, 0.9756f, 0.8669f, 0.5440f, 0.3675f, 0.7915f, 0.5583f, 1.0000f, 1.0000f, 0.7814f, 0.2532f, 1.0000f, 1.0000f, 0.9275f, 0.1836f, 0.4092f, + 1.0000f, 0.9254f, 0.6991f, 0.3033f, 0.7123f, 0.4979f, 1.0000f, 1.0000f, 1.0000f, 0.2196f, 1.0000f, 1.0000f, 1.0000f, 0.7439f, 0.3214f, 1.0000f, + 1.0000f, 1.0000f, 0.9913f, 0.9990f, 0.9260f, 1.0000f, 0.7166f, 0.8163f, 0.1280f, 1.0000f, 0.9804f, 0.9570f, 0.5137f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9986f, 0.9958f, 0.6808f, 0.7347f, 0.7269f, 0.5512f, 0.2056f, 0.9692f, 0.9311f, 0.7956f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9912f, 0.9330f, 0.8432f, 0.8578f, 0.8151f, 0.4516f, 0.2333f, 0.9808f, 0.7643f, 0.4815f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9791f, 0.9659f, 0.9233f, 0.5098f, 0.9023f, 0.6230f, 0.7385f, 1.0000f, 0.9398f, 0.6112f, 0.7403f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9765f, 0.9490f, 0.5687f, 0.8738f, 0.8088f, 0.4042f, 1.0000f, 0.6081f, 0.9160f, 0.1911f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9195f, 0.8835f, 0.5548f, 0.0989f, 0.7544f, 0.7770f, 1.0000f, 1.0000f, 0.7101f, 0.7594f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.9580f, 0.6050f, 0.3332f, 0.7527f, 0.7228f, 1.0000f, 1.0000f, 1.0000f, 0.8075f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, + 1.0000f, 0.9393f, 0.3938f, 0.6482f, 0.2400f, 0.1760f, 1.0000f, 1.0000f, 1.0000f, 0.0560f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9998f, + 1.0000f, 1.0000f, 0.9736f, 0.9949f, 0.3729f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9362f, 0.8827f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9895f, 0.9772f, 0.4191f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9402f, 0.9494f, 0.6287f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9664f, 0.9577f, 0.2127f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9200f, 0.5291f, 0.5955f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, + 1.0000f, 0.9786f, 0.9836f, 0.6900f, 0.6710f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8904f, 0.3506f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, + 1.0000f, 0.9594f, 0.8940f, 0.6019f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8304f, 0.2849f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9964f, + 1.0000f, 0.8968f, 0.5403f, 0.7901f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5756f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9953f, + 1.0000f, 0.9463f, 0.4856f, 0.7144f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7492f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9840f, 0.9846f, + 1.0000f, 0.8236f, 0.5856f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1607f, 1.0000f, 1.0000f, 1.0000f, 0.9910f, 0.9903f, 0.8559f, + 1.0000f, 0.9983f, 0.9999f, 0.9988f, 1.0000f, 0.9367f, 0.8747f, 0.9723f, 1.0000f, 0.9713f, 0.9100f, 0.9777f, 1.0000f, 0.9908f, 0.9905f, 0.9823f, + 1.0000f, 0.9998f, 0.9998f, 0.9524f, 1.0000f, 0.8713f, 0.9498f, 0.9708f, 1.0000f, 0.9002f, 0.9584f, 0.9849f, 1.0000f, 0.9597f, 0.9860f, 0.8493f, + 1.0000f, 0.9610f, 0.9926f, 0.9847f, 1.0000f, 0.8550f, 0.9753f, 1.0000f, 1.0000f, 0.8315f, 0.9620f, 1.0000f, 1.0000f, 0.6760f, 0.8540f, 0.9183f, + 1.0000f, 0.9178f, 0.9763f, 0.8270f, 1.0000f, 0.9487f, 1.0000f, 1.0000f, 1.0000f, 0.9353f, 1.0000f, 1.0000f, 1.0000f, 0.8063f, 0.9320f, 0.9884f, + 1.0000f, 0.8873f, 0.8521f, 0.9799f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7692f, 0.9371f, 1.0000f, + 1.0000f, 0.8200f, 0.9590f, 0.9531f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8587f, 1.0000f, 1.0000f, + 1.0000f, 0.3620f, 0.8788f, 0.9784f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7660f, 0.9629f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9959f, 0.9900f, 0.9049f, 0.5366f, 0.6946f, 0.7858f, 0.9520f, 0.9687f, 0.8348f, 0.8911f, 0.9876f, 1.0000f, 0.9172f, 0.9635f, 0.9810f, + 1.0000f, 0.9996f, 0.9893f, 0.9467f, 0.6560f, 0.7627f, 0.8023f, 0.9914f, 1.0000f, 0.8843f, 0.9556f, 0.9977f, 1.0000f, 0.9874f, 0.9306f, 0.9793f, + 1.0000f, 0.9448f, 0.7970f, 0.8651f, 1.0000f, 0.9118f, 1.0000f, 1.0000f, 1.0000f, 0.8954f, 1.0000f, 1.0000f, 1.0000f, 0.7058f, 0.9513f, 1.0000f, + 1.0000f, 0.9444f, 0.9431f, 0.9452f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8812f, 0.9898f, 1.0000f, + 1.0000f, 0.3834f, 0.8392f, 0.9644f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8326f, 1.0000f, 1.0000f, + 1.0000f, 0.7676f, 0.9427f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8370f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9935f, 0.9873f, 0.9741f, 0.7887f, 0.3990f, 0.5329f, 0.9291f, 0.0443f, 0.6534f, 0.8422f, 0.9928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9802f, 0.9806f, 0.8606f, 0.3391f, 0.4334f, 0.8188f, 1.0000f, 1.0000f, 0.7561f, 0.9869f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7708f, 0.9062f, 0.9955f, 0.8359f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.8858f, 0.9738f, 0.9886f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 0.8050f, 0.9423f, 1.0000f, 0.7248f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9993f, 0.9968f, + 1.0000f, 0.9149f, 1.0000f, 1.0000f, 0.1529f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9385f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1367f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9788f, 0.9228f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9829f, 0.9542f, + 1.0000f, 0.9325f, 0.9623f, 0.9567f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6831f, 0.9009f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9919f, 0.9440f, 0.9779f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7799f, 0.9842f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9999f, + 1.0000f, 0.8101f, 0.9758f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9887f, 0.9280f, + 1.0000f, 0.9211f, 0.9879f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9934f, 0.8037f, + 1.0000f, 0.9137f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9471f, 0.9638f, 0.9613f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8721f, 0.9479f, 0.8010f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9249f, 0.7510f, 0.8282f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9068f, 0.9265f, 0.9339f, + 1.0000f, 1.0000f, 1.0000f, 0.9994f, 1.0000f, 0.9997f, 0.9358f, 0.8851f, 1.0000f, 0.9733f, 0.9726f, 0.7929f, 1.0000f, 0.9966f, 0.9896f, 0.9684f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9868f, 0.8763f, 1.0000f, 1.0000f, 0.9710f, 0.8819f, 1.0000f, 1.0000f, 0.9987f, 0.9969f, 0.7873f, + 1.0000f, 0.9984f, 0.9927f, 0.9389f, 1.0000f, 0.9855f, 0.9989f, 1.0000f, 1.0000f, 0.9832f, 0.9166f, 1.0000f, 1.0000f, 0.9676f, 0.7308f, 0.8402f, + 1.0000f, 0.9976f, 0.9509f, 0.5721f, 1.0000f, 0.8212f, 1.0000f, 1.0000f, 1.0000f, 0.7457f, 1.0000f, 1.0000f, 1.0000f, 0.9871f, 0.2787f, 1.0000f, + 1.0000f, 0.9992f, 0.8804f, 0.1092f, 1.0000f, 0.8989f, 1.0000f, 1.0000f, 1.0000f, 0.8896f, 1.0000f, 1.0000f, 1.0000f, 0.9751f, 0.6428f, 1.0000f, + 1.0000f, 0.9335f, 0.4427f, 0.9946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4732f, 1.0000f, 1.0000f, + 1.0000f, 0.9962f, 0.2661f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8947f, 1.0000f, 1.0000f, + 1.0000f, 0.8660f, 0.4647f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4141f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9994f, 0.9988f, 0.9743f, 0.9951f, 0.8918f, 0.9844f, 0.9992f, 0.9979f, 0.9075f, 0.9902f, 1.0000f, 0.9857f, 0.9906f, 0.8678f, + 1.0000f, 0.9979f, 0.9989f, 0.9890f, 0.9217f, 0.9821f, 0.8224f, 1.0000f, 1.0000f, 0.9957f, 0.7754f, 1.0000f, 1.0000f, 0.9705f, 0.9607f, 0.7187f, + 1.0000f, 0.9988f, 0.9560f, 0.5215f, 1.0000f, 0.9406f, 1.0000f, 1.0000f, 1.0000f, 0.9892f, 1.0000f, 1.0000f, 1.0000f, 0.9970f, 0.4774f, 1.0000f, + 1.0000f, 0.9681f, 0.8412f, 0.7289f, 1.0000f, 0.8337f, 1.0000f, 1.0000f, 1.0000f, 0.6969f, 1.0000f, 1.0000f, 1.0000f, 0.8796f, 1.0000f, 1.0000f, + 1.0000f, 0.9950f, 0.3094f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9419f, 1.0000f, 1.0000f, + 1.0000f, 0.8381f, 0.5477f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1984f, 1.0000f, 1.0000f, + 1.0000f, 0.9721f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2265f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9933f, 0.9961f, 0.9746f, 0.8126f, 0.9728f, 0.6636f, 1.0000f, 0.3449f, 0.9948f, 0.8730f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9990f, 0.9944f, 0.9029f, 0.0172f, 0.8615f, 0.9760f, 1.0000f, 1.0000f, 0.9795f, 0.9851f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9991f, 0.8139f, 0.9376f, 0.7013f, 0.9301f, 1.0000f, 1.0000f, 1.0000f, 0.9748f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9943f, + 1.0000f, 0.9838f, 0.6784f, 1.0000f, 0.1186f, 0.9974f, 1.0000f, 1.0000f, 1.0000f, 0.9563f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9999f, + 1.0000f, 0.9775f, 0.8473f, 1.0000f, 0.1451f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 0.9939f, + 1.0000f, 0.6201f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 1.0000f, 0.9982f, + 1.0000f, 0.9106f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.9982f, + 1.0000f, 0.6344f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9999f, 0.9866f, + 1.0000f, 1.0000f, 0.9864f, 0.9587f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9929f, 0.8996f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.9942f, + 1.0000f, 0.9987f, 0.9700f, 0.8933f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9670f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, + 1.0000f, 0.9968f, 0.7724f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9834f, 0.9930f, + 1.0000f, 0.9244f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9952f, 0.9813f, + 1.0000f, 0.9315f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9528f, 0.9055f, + 1.0000f, 0.6455f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9797f, 0.9517f, 0.3273f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9286f, 0.3564f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9678f, 0.7611f, 0.4560f, + 1.0000f, 0.9999f, 0.9819f, 0.8633f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7207f, 1.0000f, 1.0000f, + 1.0000f, 0.9976f, 0.9917f, 0.9859f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8687f, 1.0000f, 1.0000f, + 1.0000f, 0.2725f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6735f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9435f, 0.8755f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8780f, 0.9882f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8483f, 1.0000f, 1.0000f, 0.7421f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, + 1.0000f, 0.9703f, 1.0000f, 1.0000f, 0.0320f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9995f, 0.9862f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0885f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9889f, 0.9995f, 0.9923f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9921f, 1.0000f, 0.9087f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9938f, 0.9016f, 0.7475f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.8866f, 0.9206f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8926f, 0.7739f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7785f, 0.9954f, 1.0000f, + 1.0000f, 0.9947f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9922f, 0.9971f, 0.9995f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, 0.9632f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8569f, 0.4287f, 0.9124f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8176f, 0.5923f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0673f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5019f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_12x4[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3987f, 1.0000f, 0.8105f, 0.9465f, 0.6269f, 1.0000f, 1.0000f, 1.0000f, 0.4786f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9946f, 0.4927f, 0.8691f, 0.9409f, 0.9569f, 0.6578f, 1.0000f, 1.0000f, 1.0000f, 0.3330f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9774f, 0.9944f, 0.6317f, 0.9052f, 0.8220f, 0.4495f, 0.2254f, 1.0000f, 1.0000f, 1.0000f, 0.6854f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9899f, 0.9969f, 0.4996f, 0.7915f, 0.7847f, 0.3712f, 0.2484f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9222f, 0.9576f, 0.0327f, 0.7824f, 0.5463f, 0.2705f, 0.5641f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9588f, 0.9649f, 0.9819f, 0.0000f, 0.7730f, 0.1103f, 0.7281f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9765f, 1.0000f, 1.0000f, 0.8239f, 0.8201f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9752f, 0.9908f, 1.0000f, 0.8276f, 0.8844f, 0.8735f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9556f, 0.9815f, 1.0000f, 0.8485f, 0.7369f, 0.4165f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9516f, 0.9700f, 0.9086f, 1.0000f, 0.7451f, 0.2920f, 0.3618f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9140f, 0.9393f, 1.0000f, 0.7892f, 0.1733f, 0.6363f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8957f, 0.8434f, 0.7064f, 1.0000f, 0.5583f, 0.1276f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9232f, 0.9870f, 1.0000f, 1.0000f, 0.8023f, 0.9005f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9643f, 0.9885f, 1.0000f, 0.7396f, 0.7581f, 0.5865f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8804f, 0.8417f, 1.0000f, 0.8124f, 0.5064f, 0.1583f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9119f, 0.9280f, 0.8615f, 1.0000f, 0.7251f, 0.3026f, 0.4857f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9242f, 0.8646f, 0.5754f, 1.0000f, 0.7129f, 0.0626f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7937f, 0.8085f, 0.3805f, 1.0000f, 0.3230f, 0.4715f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9791f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9350f, 0.9756f, 1.0000f, 1.0000f, 0.7032f, 0.7530f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9289f, 0.9613f, 1.0000f, 0.7607f, 0.8348f, 0.4076f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8469f, 0.8502f, 1.0000f, 0.7097f, 0.2132f, 0.4338f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, + 1.0000f, 0.8383f, 0.9028f, 0.3427f, 1.0000f, 0.6778f, 0.0888f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, + 1.0000f, 0.9192f, 0.6998f, 0.2005f, 1.0000f, 0.5199f, 0.1431f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9722f, 0.9911f, + 1.0000f, 0.7191f, 0.4643f, 0.2370f, 1.0000f, 0.1870f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9880f, 0.9913f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9983f, 0.9986f, 0.9933f, 0.5399f, 0.9017f, 0.8400f, 0.9384f, 0.9543f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9991f, 0.9995f, 0.9434f, 0.6659f, 0.8182f, 0.9162f, 0.8777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9851f, 0.9922f, 0.9841f, 1.0000f, 0.6410f, 0.8920f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9550f, 0.9848f, 0.8706f, 1.0000f, 0.7958f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9367f, 0.8451f, 0.9307f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8749f, 0.9202f, 0.9473f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9989f, 0.9787f, 0.8583f, 1.0000f, 0.6891f, 0.8144f, 0.9844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9973f, 0.9727f, 0.9359f, 1.0000f, 0.8044f, 0.9270f, 0.9637f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9716f, 0.7980f, 0.8763f, 1.0000f, 0.6497f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9495f, 0.9563f, 0.8969f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5919f, 0.8330f, 0.9582f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6928f, 0.9827f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9811f, 0.9855f, 0.9683f, 1.0000f, 0.4570f, 0.8567f, 0.9342f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9450f, 0.9625f, 0.7777f, 1.0000f, 0.6816f, 0.9803f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6454f, 0.8163f, 0.9261f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 0.7801f, 0.8908f, 0.9601f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 0.5523f, 0.9426f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9888f, 0.9947f, 0.9953f, + 1.0000f, 0.7682f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9935f, 0.9936f, 0.9130f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8294f, 0.9172f, 0.9442f, 1.0000f, 0.5697f, 0.8993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 1.0000f, + 1.0000f, 0.9799f, 0.8661f, 0.8981f, 1.0000f, 0.8257f, 0.9834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9985f, + 1.0000f, 0.6220f, 0.9040f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9991f, 0.9920f, + 1.0000f, 0.7870f, 0.9063f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9993f, 0.9376f, + 1.0000f, 0.7556f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9925f, 0.9882f, 0.9672f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9795f, 0.9778f, 0.7657f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9893f, 0.9977f, 0.9417f, 0.9732f, 0.8365f, 0.6171f, 0.9996f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9968f, 0.9972f, 0.9942f, 0.8001f, 0.9151f, 0.6739f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9958f, 0.9770f, 0.9595f, 1.0000f, 0.9182f, 0.9074f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9906f, 0.9689f, 0.6021f, 1.0000f, 0.5267f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9891f, 0.9619f, 0.8312f, 1.0000f, 0.9742f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9830f, 0.8882f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9660f, 0.9823f, 1.0000f, 0.9401f, 0.7424f, 0.9711f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9737f, 0.9864f, 0.9108f, 1.0000f, 0.9315f, 0.5810f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9877f, 0.8630f, 0.5334f, 1.0000f, 0.9324f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8933f, 0.7632f, 0.6537f, 1.0000f, 0.6071f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9861f, 0.8599f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9509f, 0.9631f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9867f, 0.9530f, 0.9298f, 1.0000f, 0.9458f, 0.7339f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9783f, 0.9480f, 0.5132f, 1.0000f, 0.8676f, 0.9502f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, + 1.0000f, 0.9655f, 0.6964f, 0.7222f, 1.0000f, 0.9251f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9994f, + 1.0000f, 0.8535f, 0.2596f, 1.0000f, 1.0000f, 0.9536f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, + 1.0000f, 0.9808f, 0.9896f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9858f, 0.9938f, + 1.0000f, 0.8519f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9951f, 0.9982f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9837f, 0.8895f, 0.6699f, 1.0000f, 0.8870f, 0.7504f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9987f, + 1.0000f, 0.9487f, 0.8551f, 0.3897f, 1.0000f, 0.8791f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9940f, + 1.0000f, 0.9333f, 0.3130f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9931f, 0.9980f, + 1.0000f, 0.7310f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9961f, 0.9967f, + 1.0000f, 0.9677f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9929f, 0.9904f, + 1.0000f, 0.8720f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9927f, 0.9965f, 0.8945f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9916f, 0.8065f, 0.4418f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9761f, 0.7478f, 0.7706f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5970f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8857f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6619f, 0.3522f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4252f, 0.9607f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2814f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9992f, 0.9994f, + 1.0000f, 0.7160f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9959f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9997f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 1.0000f, 0.9874f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9706f, 0.9212f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9956f, 0.9747f, 0.9666f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9962f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9918f, 0.9996f, 0.9949f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9954f, 0.9996f, 0.8831f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9523f, 0.6121f, 0.9694f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8817f, 0.7753f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9097f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9901f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_12x5[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3385f, 1.0000f, 0.8818f, 0.9311f, 0.6057f, 1.0000f, 1.0000f, 1.0000f, 0.4810f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9964f, 0.5033f, 0.8904f, 0.9448f, 0.9478f, 0.6751f, 1.0000f, 1.0000f, 1.0000f, 0.2676f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9709f, 0.9951f, 0.6474f, 0.9174f, 0.8674f, 0.5245f, 0.3884f, 1.0000f, 1.0000f, 1.0000f, 0.7693f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9930f, 0.9961f, 0.6015f, 0.8068f, 0.8243f, 0.4456f, 0.3816f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9518f, 0.9659f, 0.6327f, 0.8317f, 0.4635f, 0.3678f, 0.7032f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9685f, 0.9763f, 0.9802f, 0.0329f, 0.7475f, 0.1053f, 0.6912f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8447f, 0.9466f, 0.0000f, 0.7305f, 0.0894f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9265f, 0.8518f, 0.7498f, 0.6437f, 0.4517f, 0.6364f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 0.9872f, 1.0000f, 1.0000f, 0.8462f, 0.8490f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9826f, 0.9955f, 1.0000f, 0.8700f, 0.9032f, 0.8883f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9567f, 0.9851f, 1.0000f, 0.8585f, 0.8050f, 0.4923f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9627f, 0.9705f, 0.8840f, 1.0000f, 0.7979f, 0.4016f, 0.5141f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8974f, 0.9077f, 1.0000f, 0.8015f, 0.1211f, 0.5671f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9022f, 0.8198f, 0.6137f, 1.0000f, 0.5581f, 0.1343f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9296f, 0.8531f, 0.7227f, 1.0000f, 0.5760f, 0.2593f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8611f, 0.8033f, 0.2759f, 1.0000f, 0.1907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9415f, 0.9895f, 1.0000f, 1.0000f, 0.8228f, 0.9086f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9689f, 0.9937f, 1.0000f, 0.7672f, 0.7793f, 0.6214f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9140f, 0.8712f, 1.0000f, 0.8347f, 0.5847f, 0.2424f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9333f, 0.9319f, 0.8687f, 1.0000f, 0.7753f, 0.4272f, 0.6718f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9289f, 0.8545f, 0.3748f, 1.0000f, 0.7587f, 0.0520f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8101f, 0.7773f, 0.3310f, 1.0000f, 0.3460f, 0.4334f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, + 1.0000f, 0.8749f, 0.5932f, 0.1797f, 1.0000f, 0.6816f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9729f, + 1.0000f, 0.8213f, 0.4752f, 0.6098f, 1.0000f, 0.0710f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9832f, 0.9645f, + 1.0000f, 1.0000f, 0.9484f, 0.9781f, 1.0000f, 1.0000f, 0.7254f, 0.7543f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9340f, 0.9733f, 1.0000f, 0.7888f, 0.8649f, 0.3609f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.8662f, 0.8725f, 1.0000f, 0.7356f, 0.2840f, 0.5974f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9945f, + 1.0000f, 0.8598f, 0.9059f, 0.3535f, 1.0000f, 0.7089f, 0.1575f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, + 1.0000f, 0.9041f, 0.6943f, 0.1460f, 1.0000f, 0.6510f, 0.1686f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9880f, 0.9977f, + 1.0000f, 0.7061f, 0.2920f, 0.4145f, 1.0000f, 0.2016f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9943f, 0.9966f, + 1.0000f, 0.7961f, 0.3155f, 0.4080f, 1.0000f, 0.5296f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9578f, 0.9737f, + 1.0000f, 0.6880f, 0.2228f, 1.0000f, 1.0000f, 0.2330f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9663f, 0.9572f, 0.9422f, + 1.0000f, 0.9980f, 0.9971f, 0.9949f, 0.5088f, 0.9003f, 0.8376f, 0.9191f, 0.9507f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9982f, 0.9995f, 0.9122f, 0.6615f, 0.8433f, 0.9304f, 0.9113f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9874f, 0.9953f, 0.9893f, 1.0000f, 0.7331f, 0.9368f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9513f, 0.9823f, 0.8559f, 1.0000f, 0.8955f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9148f, 0.8862f, 0.9541f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8636f, 0.9636f, 0.9650f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5890f, 0.8390f, 0.9717f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7280f, 0.9835f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9990f, 0.9741f, 0.8361f, 1.0000f, 0.7200f, 0.8419f, 0.9890f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9978f, 0.9622f, 0.9157f, 1.0000f, 0.8134f, 0.9490f, 0.9713f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9588f, 0.7943f, 0.8807f, 1.0000f, 0.7713f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9501f, 0.9641f, 0.9216f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4867f, 0.8984f, 0.9395f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7453f, 0.9785f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6848f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9165f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9770f, 0.9806f, 0.9557f, 1.0000f, 0.4694f, 0.8572f, 0.9460f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9347f, 0.9617f, 0.7609f, 1.0000f, 0.6974f, 0.9842f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6581f, 0.8166f, 0.9068f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.7925f, 0.8945f, 0.9777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9999f, + 1.0000f, 0.6290f, 0.8965f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9999f, 0.9997f, + 1.0000f, 0.8258f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9813f, 0.9926f, 0.9281f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9883f, 0.8504f, + 1.0000f, 0.8332f, 0.9131f, 0.9326f, 1.0000f, 0.5626f, 0.9199f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, 1.0000f, + 1.0000f, 0.9721f, 0.8760f, 0.9257f, 1.0000f, 0.8476f, 0.9888f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9984f, + 1.0000f, 0.6252f, 0.9381f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9991f, 0.9909f, + 1.0000f, 0.8150f, 0.9441f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9992f, 0.9241f, + 1.0000f, 0.6176f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9898f, 0.9942f, 0.9900f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9792f, 0.9907f, 0.8924f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9774f, 0.8288f, 0.8182f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9608f, 0.9409f, 0.8303f, + 1.0000f, 1.0000f, 0.9957f, 0.9905f, 0.9402f, 0.9551f, 0.8624f, 0.6546f, 0.9989f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9948f, 0.9959f, 0.9973f, 0.7851f, 0.9472f, 0.7429f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9952f, 0.9361f, 0.9530f, 1.0000f, 0.8914f, 0.8851f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9809f, 0.9697f, 0.4978f, 1.0000f, 0.5346f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9920f, 0.9182f, 0.6684f, 1.0000f, 0.8893f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8934f, 0.7145f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9863f, 0.9013f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9654f, 0.9752f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9598f, 0.9914f, 1.0000f, 0.9672f, 0.7733f, 0.9756f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9816f, 0.9869f, 0.9104f, 1.0000f, 0.9495f, 0.6401f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9938f, 0.8273f, 0.4208f, 1.0000f, 0.9249f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8784f, 0.7565f, 0.5490f, 1.0000f, 0.5716f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9701f, 0.5803f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8118f, 0.7997f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9799f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9233f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9860f, 0.9795f, 0.9429f, 1.0000f, 0.9546f, 0.7869f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9829f, 0.9524f, 0.5443f, 1.0000f, 0.9095f, 0.9725f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 0.9667f, 0.6650f, 0.7117f, 1.0000f, 0.9435f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9996f, + 1.0000f, 0.8829f, 0.2123f, 1.0000f, 1.0000f, 0.9693f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9995f, + 1.0000f, 0.8994f, 0.9224f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, 0.9967f, + 1.0000f, 0.5395f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9970f, 0.9996f, + 1.0000f, 0.9744f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9885f, 0.9935f, + 1.0000f, 0.9845f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9680f, 0.9902f, 0.9877f, + 1.0000f, 0.9866f, 0.9354f, 0.7380f, 1.0000f, 0.9273f, 0.7813f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.9962f, + 1.0000f, 0.9676f, 0.8795f, 0.4396f, 1.0000f, 0.8873f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9981f, 0.9911f, + 1.0000f, 0.9593f, 0.2510f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9932f, + 1.0000f, 0.7630f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9956f, 0.9965f, + 1.0000f, 0.8772f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9854f, 0.9767f, + 1.0000f, 0.5194f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9933f, 0.9916f, 0.7003f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9928f, 0.9759f, 0.9375f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9918f, 0.9603f, 0.9839f, + 1.0000f, 0.9979f, 0.7832f, 0.4576f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9819f, 0.7906f, 0.7651f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3077f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7405f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6784f, 0.3232f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3950f, 0.9788f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, 0.9996f, + 1.0000f, 0.7520f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, 0.9946f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 1.0000f, 0.9998f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9960f, 1.0000f, 0.9968f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9562f, 0.8737f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9535f, 0.9454f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9631f, 0.9050f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9388f, 0.9974f, 1.0000f, + 1.0000f, 0.9998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9848f, 0.9989f, 0.9922f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9857f, 0.9999f, 0.8405f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9748f, 0.5536f, 0.9583f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9208f, 0.8085f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7173f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9613f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_12x6[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.4495f, 1.0000f, 0.9421f, 0.9517f, 0.7621f, 1.0000f, 1.0000f, 1.0000f, 0.4827f, 1.0000f, 0.8797f, 0.9512f, + 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.6889f, 0.9444f, 0.9633f, 0.9713f, 0.7033f, 1.0000f, 1.0000f, 1.0000f, 0.2638f, 1.0000f, 0.8294f, 0.9784f, + 1.0000f, 1.0000f, 0.9823f, 0.9970f, 0.6859f, 0.9375f, 0.9393f, 0.5485f, 0.3832f, 1.0000f, 1.0000f, 1.0000f, 0.7745f, 1.0000f, 0.9591f, 0.9129f, + 1.0000f, 1.0000f, 0.9882f, 0.9939f, 0.7113f, 0.8930f, 0.8759f, 0.5041f, 0.3565f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9665f, 0.9507f, 0.9281f, + 1.0000f, 1.0000f, 0.9836f, 0.9730f, 0.7294f, 0.8913f, 0.5839f, 0.4607f, 0.7344f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9532f, 0.9416f, 0.7269f, + 1.0000f, 0.9778f, 0.9935f, 0.9828f, 0.0834f, 0.8558f, 0.1109f, 0.7512f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9201f, 0.9084f, 0.5666f, + 1.0000f, 1.0000f, 0.9608f, 0.9471f, 0.0187f, 0.8450f, 0.0373f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9187f, 0.7466f, 0.3132f, + 1.0000f, 0.9668f, 0.8905f, 0.7218f, 0.6538f, 0.4989f, 0.4881f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9165f, 0.6078f, 0.6734f, + 1.0000f, 1.0000f, 1.0000f, 0.9864f, 1.0000f, 1.0000f, 0.9357f, 0.8768f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9820f, 0.9980f, 1.0000f, 0.8730f, 0.9351f, 0.9029f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9756f, 0.9866f, 1.0000f, 0.9037f, 0.8815f, 0.5438f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9759f, 0.9812f, 0.8593f, 1.0000f, 0.8778f, 0.4935f, 0.5753f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9587f, 0.9158f, 1.0000f, 0.8922f, 0.1996f, 0.6637f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9497f, 0.8462f, 0.6472f, 1.0000f, 0.6947f, 0.2723f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9746f, 0.9288f, 0.6918f, 1.0000f, 0.7394f, 0.1897f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9256f, 0.7825f, 0.3766f, 1.0000f, 0.1350f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9433f, 0.9957f, 0.8437f, 1.0000f, 0.8963f, 0.9235f, 0.3495f, 1.0000f, 1.0000f, 1.0000f, 0.7663f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9878f, 0.9916f, 0.7556f, 0.8740f, 0.8334f, 0.6505f, 0.1794f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9560f, 0.8399f, 0.7844f, 0.9005f, 0.6797f, 0.3632f, 0.1231f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9616f, 0.9492f, 0.8570f, 0.5195f, 0.8852f, 0.4662f, 0.7087f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9541f, 0.9180f, 0.4381f, 0.8109f, 0.8690f, 0.0976f, 1.0000f, 0.6404f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8824f, 0.8347f, 0.3958f, 0.0687f, 0.5530f, 0.5621f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, + 1.0000f, 0.9398f, 0.5881f, 0.2094f, 0.6829f, 0.8060f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, + 1.0000f, 0.8980f, 0.3699f, 0.6266f, 0.1691f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9972f, 0.9942f, + 1.0000f, 1.0000f, 0.9649f, 0.9896f, 1.0000f, 1.0000f, 0.8373f, 0.7919f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9595f, 0.9810f, 1.0000f, 0.8870f, 0.8996f, 0.4081f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9091f, 0.8581f, 0.0535f, 0.8139f, 0.4143f, 0.6154f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, + 1.0000f, 0.9339f, 0.9215f, 0.3284f, 0.6116f, 0.8487f, 0.2463f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, + 1.0000f, 0.9683f, 0.7991f, 0.2283f, 1.0000f, 0.7489f, 0.3054f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9908f, 0.9988f, + 1.0000f, 0.8281f, 0.3355f, 0.5246f, 1.0000f, 0.3208f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9975f, 0.9960f, + 1.0000f, 0.9021f, 0.2551f, 0.3895f, 1.0000f, 0.6604f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9899f, 0.9975f, + 1.0000f, 0.7684f, 0.2373f, 1.0000f, 1.0000f, 0.2189f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9940f, 0.9927f, 0.9600f, + 1.0000f, 0.9982f, 0.9982f, 0.9919f, 0.4204f, 0.9122f, 0.8360f, 0.9455f, 0.9242f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, 0.9657f, 0.8896f, + 1.0000f, 0.9983f, 0.9998f, 0.9194f, 0.5709f, 0.8523f, 0.9208f, 0.9487f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9698f, 0.9427f, 0.6766f, + 1.0000f, 0.9676f, 0.9870f, 0.9804f, 1.0000f, 0.7599f, 0.9275f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7956f, 0.7882f, 0.9326f, + 1.0000f, 0.9099f, 0.9750f, 0.8267f, 1.0000f, 0.8861f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8184f, 0.9136f, 0.9876f, + 1.0000f, 0.9114f, 0.8887f, 0.9793f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7004f, 0.9621f, 1.0000f, + 1.0000f, 0.8604f, 0.9661f, 0.9653f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8321f, 1.0000f, 1.0000f, + 1.0000f, 0.5961f, 0.9269f, 0.9680f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8026f, 0.9850f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9991f, 0.9737f, 0.8254f, 1.0000f, 0.7578f, 0.8412f, 0.9815f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9977f, 0.9706f, 0.9173f, 1.0000f, 0.8154f, 0.9381f, 0.9787f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9522f, 0.7725f, 0.8511f, 1.0000f, 0.8043f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9313f, 0.9404f, 0.9107f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5093f, 0.8939f, 0.9564f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7974f, 0.9645f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7805f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8955f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9796f, 0.9743f, 0.9578f, 1.0000f, 0.5296f, 0.8626f, 0.9569f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9502f, 0.9672f, 0.7938f, 1.0000f, 0.7140f, 0.9726f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6192f, 0.8169f, 0.8700f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7704f, 0.8546f, 0.9765f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.7192f, 0.9068f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9997f, 0.9999f, + 1.0000f, 0.8475f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, 0.9933f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9936f, 0.9807f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9961f, 0.9798f, + 1.0000f, 0.8535f, 0.9262f, 0.9476f, 1.0000f, 0.5796f, 0.8680f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9998f, + 1.0000f, 0.9762f, 0.8749f, 0.9013f, 1.0000f, 0.8076f, 0.9874f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9984f, 0.9971f, + 1.0000f, 0.6370f, 0.9144f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9984f, 0.9733f, + 1.0000f, 0.8307f, 0.9410f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9966f, 0.8637f, + 1.0000f, 0.6336f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9848f, 0.9963f, 0.9910f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9723f, 0.9868f, 0.8972f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9894f, 0.8878f, 0.9052f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9790f, 0.9691f, 0.9551f, + 1.0000f, 1.0000f, 0.9892f, 0.9945f, 0.9060f, 0.9833f, 0.8615f, 0.7166f, 0.9967f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.9818f, 0.9923f, + 1.0000f, 0.9965f, 0.9981f, 0.9988f, 0.6702f, 0.9687f, 0.7901f, 0.9998f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9857f, 0.9838f, 0.9465f, + 1.0000f, 0.9965f, 0.9918f, 0.9387f, 1.0000f, 0.9555f, 0.8227f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9801f, 0.9629f, 0.9941f, + 1.0000f, 0.9952f, 0.9781f, 0.3426f, 1.0000f, 0.5575f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9950f, 0.9076f, 1.0000f, + 1.0000f, 0.9985f, 0.9294f, 0.5392f, 1.0000f, 0.8834f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9872f, 0.9951f, 1.0000f, + 1.0000f, 0.9546f, 0.6670f, 0.9968f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8988f, 1.0000f, 1.0000f, + 1.0000f, 0.9937f, 0.7370f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9716f, 1.0000f, 1.0000f, + 1.0000f, 0.9229f, 0.8947f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9641f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9978f, 0.9913f, 1.0000f, 0.9845f, 0.7785f, 0.9709f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9898f, 0.9926f, 0.9449f, 1.0000f, 0.9527f, 0.6571f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9964f, 0.9222f, 0.2892f, 1.0000f, 0.9604f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9740f, 0.7244f, 0.4551f, 1.0000f, 0.5921f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9859f, 0.4020f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8720f, 0.6438f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9720f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7060f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9886f, 0.9840f, 0.9482f, 1.0000f, 0.9775f, 0.7319f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9884f, 0.9537f, 0.6000f, 1.0000f, 0.8787f, 0.9438f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.9831f, 0.6229f, 0.6039f, 1.0000f, 0.9332f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.9151f, 0.1467f, 1.0000f, 1.0000f, 0.9363f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9987f, + 1.0000f, 0.9612f, 0.7863f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9994f, + 1.0000f, 0.4264f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9958f, 1.0000f, + 1.0000f, 0.9249f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9915f, 0.9997f, + 1.0000f, 0.8659f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9911f, 0.9992f, 0.9976f, + 1.0000f, 0.9901f, 0.9637f, 0.7765f, 1.0000f, 0.9460f, 0.7443f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9948f, 0.9953f, + 1.0000f, 0.9772f, 0.8843f, 0.5345f, 1.0000f, 0.8212f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 0.9852f, + 1.0000f, 0.9855f, 0.2975f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9930f, + 1.0000f, 0.8093f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9929f, 0.9991f, 0.9946f, + 1.0000f, 0.9045f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9947f, 0.9954f, 0.9769f, + 1.0000f, 0.2809f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9962f, 0.9903f, 0.6976f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9888f, 0.8425f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9890f, 0.9301f, 0.9320f, + 1.0000f, 0.9921f, 0.8499f, 0.4772f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8710f, 1.0000f, 1.0000f, + 1.0000f, 0.9825f, 0.8198f, 0.8240f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9582f, 1.0000f, 1.0000f, + 1.0000f, 0.1579f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6301f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7534f, 0.4323f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5145f, 0.9573f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4438f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, + 1.0000f, 0.8009f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, 0.9880f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9956f, 1.0000f, 0.9989f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9979f, 1.0000f, 0.9753f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9695f, 0.8806f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9843f, 0.9702f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9625f, 0.8648f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8386f, 0.9995f, 1.0000f, + 1.0000f, 0.9932f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, 0.9990f, 0.9905f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9996f, 0.8669f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9345f, 0.4718f, 0.9307f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8124f, 0.7419f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7642f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9369f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_12x8[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5588f, 1.0000f, 0.9555f, 0.9382f, 0.7966f, 1.0000f, 0.8855f, 0.9307f, 0.5111f, 1.0000f, 0.9837f, 0.9961f, + 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.7459f, 0.9753f, 0.9716f, 0.9745f, 0.7119f, 0.9180f, 0.9366f, 0.9447f, 0.2944f, 1.0000f, 0.9984f, 0.9977f, + 1.0000f, 1.0000f, 0.9795f, 0.9985f, 0.7823f, 0.9875f, 0.9631f, 0.6537f, 0.5466f, 0.9551f, 0.9497f, 0.7555f, 0.8055f, 1.0000f, 0.9832f, 0.9372f, + 1.0000f, 1.0000f, 0.9958f, 0.9928f, 0.7856f, 0.9324f, 0.9187f, 0.5956f, 0.4727f, 0.9296f, 0.9130f, 0.6180f, 1.0000f, 0.9859f, 0.9798f, 0.9590f, + 1.0000f, 1.0000f, 0.9783f, 0.9547f, 0.7142f, 0.9340f, 0.6273f, 0.5989f, 0.7756f, 0.9280f, 0.7721f, 0.4374f, 1.0000f, 0.9722f, 0.9488f, 0.6334f, + 1.0000f, 0.9903f, 0.9917f, 0.9750f, 0.1410f, 0.9042f, 0.2259f, 0.8376f, 1.0000f, 0.9136f, 0.4580f, 0.9216f, 1.0000f, 0.9251f, 0.8903f, 0.6054f, + 1.0000f, 1.0000f, 0.9719f, 0.9433f, 0.1210f, 0.9035f, 0.0611f, 1.0000f, 1.0000f, 0.8465f, 0.1681f, 1.0000f, 1.0000f, 0.9605f, 0.6566f, 0.3930f, + 1.0000f, 0.9786f, 0.8707f, 0.6808f, 0.6622f, 0.5338f, 0.4921f, 1.0000f, 1.0000f, 0.7419f, 0.7593f, 1.0000f, 1.0000f, 0.9302f, 0.5017f, 0.7399f, + 1.0000f, 1.0000f, 1.0000f, 0.9957f, 1.0000f, 1.0000f, 0.9582f, 0.9028f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9948f, + 1.0000f, 1.0000f, 0.9952f, 0.9942f, 1.0000f, 0.9734f, 0.9679f, 0.9143f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9916f, 0.9924f, + 1.0000f, 1.0000f, 0.9899f, 0.9852f, 1.0000f, 0.9313f, 0.9174f, 0.6242f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9666f, 0.9506f, + 1.0000f, 0.9878f, 0.9918f, 0.8600f, 1.0000f, 0.9392f, 0.6211f, 0.6980f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9768f, 0.9841f, 0.6705f, + 1.0000f, 1.0000f, 0.9707f, 0.8863f, 1.0000f, 0.9103f, 0.3685f, 0.7839f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9685f, 0.8779f, 0.4678f, + 1.0000f, 0.9773f, 0.8529f, 0.5381f, 1.0000f, 0.7498f, 0.4530f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9007f, 0.5779f, 0.6117f, + 1.0000f, 0.9790f, 0.8847f, 0.6086f, 1.0000f, 0.7358f, 0.2569f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9334f, 0.4479f, 0.5851f, + 1.0000f, 0.9423f, 0.7612f, 0.3988f, 1.0000f, 0.1593f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8341f, 0.4159f, 1.0000f, + 1.0000f, 1.0000f, 0.9815f, 0.9983f, 0.9049f, 1.0000f, 0.9377f, 0.9110f, 0.1767f, 1.0000f, 1.0000f, 1.0000f, 0.6480f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9925f, 0.9938f, 0.7252f, 0.9465f, 0.8871f, 0.6731f, 0.2795f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9656f, 0.8688f, 0.8364f, 0.9620f, 0.7337f, 0.5507f, 0.0864f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9793f, 0.9645f, 0.8590f, 0.3871f, 0.9329f, 0.5887f, 0.8069f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9725f, 0.9257f, 0.4046f, 0.8725f, 0.8993f, 0.2338f, 1.0000f, 0.4268f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9240f, 0.8539f, 0.4214f, 0.0177f, 0.6594f, 0.7209f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, + 1.0000f, 0.9535f, 0.5815f, 0.2492f, 0.7649f, 0.8139f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, + 1.0000f, 0.9070f, 0.3300f, 0.5742f, 0.0985f, 0.0349f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9969f, 0.9981f, + 1.0000f, 1.0000f, 0.9809f, 0.9877f, 1.0000f, 1.0000f, 0.8152f, 0.7981f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9755f, 0.9842f, 1.0000f, 0.9205f, 0.8770f, 0.5064f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9397f, 0.8956f, 0.2720f, 0.8971f, 0.5294f, 0.7050f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9934f, + 1.0000f, 0.9470f, 0.9543f, 0.5204f, 0.4776f, 0.8697f, 0.4103f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9887f, + 1.0000f, 0.9698f, 0.7919f, 0.3017f, 1.0000f, 0.7950f, 0.5249f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9894f, 0.9987f, + 1.0000f, 0.8486f, 0.3432f, 0.6508f, 1.0000f, 0.5158f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9988f, + 1.0000f, 0.8895f, 0.2016f, 0.3496f, 1.0000f, 0.7004f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9935f, 0.9974f, + 1.0000f, 0.7806f, 0.2870f, 1.0000f, 1.0000f, 0.3090f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9872f, 0.9921f, 0.9350f, + 1.0000f, 0.9995f, 0.9970f, 0.9964f, 0.4426f, 0.9077f, 0.8669f, 0.9479f, 0.9413f, 0.9156f, 0.7439f, 0.7379f, 1.0000f, 0.9956f, 0.9992f, 0.9788f, + 1.0000f, 0.9999f, 0.9998f, 0.9285f, 0.5627f, 0.8678f, 0.9246f, 0.9676f, 1.0000f, 0.8166f, 0.7668f, 0.7686f, 1.0000f, 0.9910f, 0.9926f, 0.8926f, + 1.0000f, 0.9418f, 0.9883f, 0.9807f, 1.0000f, 0.8268f, 0.9601f, 1.0000f, 1.0000f, 0.7274f, 0.9739f, 1.0000f, 1.0000f, 0.8293f, 0.9021f, 0.9943f, + 1.0000f, 0.8941f, 0.9642f, 0.8192f, 1.0000f, 0.9442f, 1.0000f, 1.0000f, 1.0000f, 0.8218f, 1.0000f, 1.0000f, 1.0000f, 0.8919f, 0.9766f, 0.9950f, + 1.0000f, 0.8813f, 0.8560f, 0.9737f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8179f, 0.9567f, 1.0000f, + 1.0000f, 0.8305f, 0.9539f, 0.9408f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9527f, 1.0000f, 1.0000f, + 1.0000f, 0.5424f, 0.9274f, 0.9776f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8125f, 0.9760f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9984f, 0.9854f, 0.8497f, 1.0000f, 0.7888f, 0.8839f, 0.9863f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9623f, 0.9510f, 0.9514f, + 1.0000f, 0.9959f, 0.9649f, 0.9263f, 1.0000f, 0.8387f, 0.9519f, 0.9813f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9828f, 0.9193f, 0.9228f, + 1.0000f, 0.9523f, 0.7872f, 0.8421f, 1.0000f, 0.8805f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7631f, 0.9428f, 1.0000f, + 1.0000f, 0.9222f, 0.9437f, 0.9361f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8761f, 0.9873f, 1.0000f, + 1.0000f, 0.3748f, 0.8243f, 0.9594f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8978f, 1.0000f, 1.0000f, + 1.0000f, 0.7517f, 0.9291f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7935f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8743f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9826f, 0.9802f, 0.9616f, 0.8454f, 0.5666f, 0.8788f, 0.9704f, 0.1105f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9612f, 0.9688f, 0.8011f, 0.4970f, 0.7316f, 0.9870f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6650f, 0.8610f, 0.9403f, 0.8432f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.8098f, 0.9149f, 0.9811f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7231f, 0.9162f, 1.0000f, 0.7574f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, 0.9989f, + 1.0000f, 0.8620f, 1.0000f, 1.0000f, 0.1504f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9804f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0481f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9966f, 0.9742f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.9839f, + 1.0000f, 0.8949f, 0.9461f, 0.9493f, 1.0000f, 0.6022f, 0.8911f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9999f, + 1.0000f, 0.9834f, 0.9116f, 0.9578f, 1.0000f, 0.8410f, 0.9929f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, + 1.0000f, 0.7164f, 0.9531f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9954f, 0.9563f, + 1.0000f, 0.8580f, 0.9713f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9914f, 0.8280f, + 1.0000f, 0.6422f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9659f, 0.9937f, 0.9848f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9211f, 0.9830f, 0.8399f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9758f, 0.8734f, 0.9199f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9771f, 0.9763f, 0.9701f, + 1.0000f, 1.0000f, 0.9999f, 0.9893f, 0.9123f, 0.9945f, 0.8830f, 0.7704f, 0.9897f, 0.9933f, 0.9728f, 0.8317f, 1.0000f, 0.9986f, 0.9920f, 0.9962f, + 1.0000f, 0.9998f, 0.9999f, 0.9960f, 0.6678f, 0.9634f, 0.8329f, 1.0000f, 1.0000f, 0.9907f, 0.9083f, 1.0000f, 1.0000f, 0.9988f, 0.9992f, 0.8752f, + 1.0000f, 0.9999f, 0.9970f, 0.9318f, 1.0000f, 0.9900f, 0.9387f, 1.0000f, 1.0000f, 0.9973f, 0.9885f, 1.0000f, 1.0000f, 0.9995f, 0.8476f, 0.9502f, + 1.0000f, 0.9981f, 0.9846f, 0.3162f, 1.0000f, 0.6858f, 1.0000f, 1.0000f, 1.0000f, 0.8716f, 1.0000f, 1.0000f, 1.0000f, 0.9932f, 0.7996f, 1.0000f, + 1.0000f, 0.9977f, 0.8796f, 0.2097f, 1.0000f, 0.8640f, 1.0000f, 1.0000f, 1.0000f, 0.9800f, 1.0000f, 1.0000f, 1.0000f, 0.9731f, 0.9097f, 1.0000f, + 1.0000f, 0.9710f, 0.4873f, 0.9844f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7073f, 1.0000f, 1.0000f, + 1.0000f, 0.9818f, 0.4824f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9268f, 1.0000f, 1.0000f, + 1.0000f, 0.9063f, 0.6907f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8256f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9982f, 0.9857f, 1.0000f, 0.9912f, 0.8040f, 0.9880f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9850f, 0.9890f, 0.9234f, + 1.0000f, 0.9940f, 0.9975f, 0.9781f, 1.0000f, 0.9586f, 0.7739f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9913f, 0.9638f, 0.8549f, + 1.0000f, 0.9973f, 0.8963f, 0.2644f, 1.0000f, 0.9672f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.7904f, 1.0000f, + 1.0000f, 0.9609f, 0.6782f, 0.3810f, 1.0000f, 0.6393f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9669f, 1.0000f, 1.0000f, + 1.0000f, 0.9820f, 0.3366f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9822f, 1.0000f, 1.0000f, + 1.0000f, 0.8649f, 0.4629f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7790f, 1.0000f, 1.0000f, + 1.0000f, 0.9778f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.3232f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9980f, 0.9930f, 0.9682f, 0.8570f, 0.9868f, 0.7773f, 1.0000f, 0.7097f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9975f, 0.9575f, 0.7027f, 0.2178f, 0.9014f, 0.9571f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9865f, 0.7187f, 0.6757f, 0.6451f, 0.9168f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 1.0000f, + 1.0000f, 0.9695f, 0.1934f, 1.0000f, 0.2415f, 0.9627f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, + 1.0000f, 0.9662f, 0.6833f, 1.0000f, 0.1314f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9965f, 0.9965f, + 1.0000f, 0.3622f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9990f, 1.0000f, + 1.0000f, 0.8879f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9888f, 0.9994f, + 1.0000f, 0.6148f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9955f, 0.9978f, 0.9953f, + 1.0000f, 0.9963f, 0.9747f, 0.8084f, 1.0000f, 0.9692f, 0.7295f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9972f, + 1.0000f, 0.9824f, 0.9056f, 0.7479f, 1.0000f, 0.8630f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9947f, + 1.0000f, 0.9909f, 0.4321f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9968f, + 1.0000f, 0.8444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9891f, 0.9896f, + 1.0000f, 0.9356f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9976f, 0.9652f, + 1.0000f, 0.1851f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9941f, 0.9882f, 0.5923f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9856f, 0.7536f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, 0.8822f, 0.8518f, + 1.0000f, 0.9939f, 0.8934f, 0.6932f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8112f, 1.0000f, 1.0000f, + 1.0000f, 0.9982f, 0.8887f, 0.9475f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9922f, 1.0000f, 1.0000f, + 1.0000f, 0.0739f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5704f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8231f, 0.6883f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6956f, 0.9866f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6364f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 1.0000f, 1.0000f, + 1.0000f, 0.9090f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9905f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9906f, 0.9997f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9946f, 0.9996f, 0.9484f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9971f, 0.9559f, 0.8026f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9598f, 0.9451f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9456f, 0.8508f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8659f, 0.9979f, 1.0000f, + 1.0000f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9991f, 0.9979f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9902f, 0.9998f, 0.9345f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9000f, 0.3559f, 0.8985f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8353f, 0.6303f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5548f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8205f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_12x10[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6207f, 1.0000f, 0.9776f, 0.9505f, 0.7947f, 1.0000f, 0.9931f, 0.9859f, 0.4908f, 1.0000f, 0.9972f, 0.9997f, + 1.0000f, 1.0000f, 1.0000f, 0.9980f, 0.7324f, 0.9738f, 0.9791f, 0.9809f, 0.7362f, 0.9959f, 0.9913f, 0.9638f, 0.2599f, 1.0000f, 0.9977f, 0.9994f, + 1.0000f, 1.0000f, 0.9957f, 0.9991f, 0.7556f, 0.9800f, 0.9550f, 0.6656f, 0.5596f, 0.9935f, 0.9709f, 0.7168f, 0.8272f, 1.0000f, 0.9874f, 0.9291f, + 1.0000f, 1.0000f, 0.9961f, 0.9844f, 0.8027f, 0.9422f, 0.9112f, 0.6472f, 0.4826f, 0.9821f, 0.9340f, 0.6631f, 1.0000f, 0.9882f, 0.9592f, 0.9172f, + 1.0000f, 1.0000f, 0.9898f, 0.9717f, 0.7343f, 0.9572f, 0.7065f, 0.6914f, 0.8340f, 0.9606f, 0.7208f, 0.6299f, 1.0000f, 0.9833f, 0.9493f, 0.5704f, + 1.0000f, 0.9922f, 0.9852f, 0.9539f, 0.2317f, 0.9211f, 0.3620f, 0.8999f, 1.0000f, 0.9194f, 0.3453f, 0.9068f, 1.0000f, 0.9687f, 0.8601f, 0.5523f, + 1.0000f, 1.0000f, 0.9535f, 0.9074f, 0.1950f, 0.8782f, 0.0978f, 1.0000f, 1.0000f, 0.9386f, 0.1450f, 1.0000f, 1.0000f, 0.9489f, 0.5947f, 0.3046f, + 1.0000f, 0.9760f, 0.8551f, 0.5845f, 0.6847f, 0.6047f, 0.6176f, 1.0000f, 1.0000f, 0.6731f, 0.7147f, 1.0000f, 1.0000f, 0.9020f, 0.4045f, 0.6500f, + 1.0000f, 1.0000f, 1.0000f, 0.9963f, 1.0000f, 1.0000f, 0.9666f, 0.9296f, 1.0000f, 1.0000f, 0.9856f, 0.9395f, 1.0000f, 1.0000f, 0.9986f, 0.9972f, + 1.0000f, 1.0000f, 0.9960f, 0.9991f, 1.0000f, 0.9589f, 0.9452f, 0.9148f, 1.0000f, 0.9876f, 0.9881f, 0.9061f, 1.0000f, 1.0000f, 0.9956f, 0.9728f, + 1.0000f, 1.0000f, 0.9905f, 0.9837f, 1.0000f, 0.9582f, 0.8941f, 0.6527f, 1.0000f, 0.9733f, 0.9448f, 0.6754f, 1.0000f, 1.0000f, 0.9798f, 0.9528f, + 1.0000f, 0.9871f, 0.9947f, 0.8712f, 1.0000f, 0.9404f, 0.6358f, 0.7106f, 1.0000f, 0.9579f, 0.6605f, 0.6329f, 1.0000f, 0.9813f, 0.9817f, 0.6824f, + 1.0000f, 1.0000f, 0.9750f, 0.9200f, 1.0000f, 0.9532f, 0.4742f, 0.8629f, 1.0000f, 0.9565f, 0.4614f, 0.8620f, 1.0000f, 0.9893f, 0.8948f, 0.5913f, + 1.0000f, 0.9755f, 0.8738f, 0.6144f, 1.0000f, 0.8000f, 0.5739f, 1.0000f, 1.0000f, 0.8307f, 0.3565f, 1.0000f, 1.0000f, 0.9250f, 0.5486f, 0.7470f, + 1.0000f, 0.9787f, 0.8919f, 0.5375f, 1.0000f, 0.7488f, 0.4148f, 1.0000f, 1.0000f, 0.8373f, 0.3164f, 1.0000f, 1.0000f, 0.9265f, 0.4524f, 0.6681f, + 1.0000f, 0.9426f, 0.6980f, 0.2734f, 1.0000f, 0.2862f, 1.0000f, 1.0000f, 1.0000f, 0.4388f, 1.0000f, 1.0000f, 1.0000f, 0.8190f, 0.5560f, 1.0000f, + 1.0000f, 1.0000f, 0.9879f, 0.9975f, 0.9118f, 1.0000f, 0.9501f, 0.9270f, 0.1541f, 1.0000f, 0.7790f, 0.8730f, 0.5300f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9951f, 0.9973f, 0.6801f, 0.9648f, 0.8591f, 0.6778f, 0.1875f, 0.7849f, 0.8284f, 0.6936f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9767f, 0.8903f, 0.8226f, 0.9730f, 0.7505f, 0.5810f, 0.0442f, 0.9047f, 0.7700f, 0.5262f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9863f, 0.9714f, 0.8880f, 0.3340f, 0.9609f, 0.6387f, 0.8166f, 1.0000f, 0.8864f, 0.7044f, 0.7267f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9896f, 0.9485f, 0.4950f, 0.8395f, 0.9034f, 0.3675f, 1.0000f, 0.3782f, 0.8541f, 0.2667f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9430f, 0.8703f, 0.4867f, 0.0177f, 0.7188f, 0.8014f, 1.0000f, 1.0000f, 0.7961f, 0.7685f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.9286f, 0.5109f, 0.2245f, 0.7654f, 0.8521f, 1.0000f, 1.0000f, 1.0000f, 0.8066f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, + 1.0000f, 0.9013f, 0.2798f, 0.4990f, 0.0771f, 0.1074f, 1.0000f, 1.0000f, 1.0000f, 0.2099f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9999f, + 1.0000f, 1.0000f, 0.9887f, 0.9901f, 0.4295f, 1.0000f, 0.8469f, 0.8078f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9740f, 0.9802f, 0.6870f, 0.9516f, 0.8848f, 0.4658f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9557f, 0.9260f, 0.3396f, 0.9228f, 0.5632f, 0.7023f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, + 1.0000f, 0.9561f, 0.9568f, 0.5225f, 0.5148f, 0.9223f, 0.4342f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, + 1.0000f, 0.9866f, 0.8561f, 0.4247f, 1.0000f, 0.8459f, 0.6014f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9916f, 0.9994f, + 1.0000f, 0.8832f, 0.3993f, 0.7286f, 1.0000f, 0.6079f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9932f, + 1.0000f, 0.9160f, 0.2025f, 0.4097f, 1.0000f, 0.7001f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9941f, 0.9915f, + 1.0000f, 0.7606f, 0.3282f, 1.0000f, 1.0000f, 0.3728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9827f, 0.9962f, 0.9054f, + 1.0000f, 0.9994f, 0.9997f, 0.9988f, 0.4479f, 0.9473f, 0.8840f, 0.9575f, 0.9460f, 0.9481f, 0.9041f, 0.9400f, 1.0000f, 0.9936f, 0.9979f, 0.9869f, + 1.0000f, 0.9998f, 0.9998f, 0.9391f, 0.5775f, 0.8790f, 0.9301f, 0.9743f, 1.0000f, 0.9177f, 0.9554f, 0.9825f, 1.0000f, 0.9911f, 0.9929f, 0.9087f, + 1.0000f, 0.9335f, 0.9672f, 0.9654f, 1.0000f, 0.8438f, 0.9619f, 1.0000f, 1.0000f, 0.8129f, 0.9657f, 1.0000f, 1.0000f, 0.7761f, 0.8934f, 0.9925f, + 1.0000f, 0.8956f, 0.9596f, 0.7877f, 1.0000f, 0.9359f, 1.0000f, 1.0000f, 1.0000f, 0.9439f, 1.0000f, 1.0000f, 1.0000f, 0.8872f, 0.9622f, 0.9963f, + 1.0000f, 0.8970f, 0.8648f, 0.9684f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7820f, 0.9435f, 1.0000f, + 1.0000f, 0.8249f, 0.9632f, 0.9735f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9100f, 1.0000f, 1.0000f, + 1.0000f, 0.3889f, 0.8531f, 0.9701f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7589f, 0.9363f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9986f, 0.9757f, 0.8815f, 1.0000f, 0.8153f, 0.8807f, 0.9854f, 1.0000f, 0.7987f, 0.7905f, 0.9136f, 1.0000f, 0.9651f, 0.9782f, 0.9848f, + 1.0000f, 0.9990f, 0.9720f, 0.9330f, 1.0000f, 0.8823f, 0.9669f, 0.9914f, 1.0000f, 0.8318f, 0.8685f, 0.9939f, 1.0000f, 0.9902f, 0.9612f, 0.9769f, + 1.0000f, 0.9354f, 0.7522f, 0.8104f, 1.0000f, 0.9106f, 1.0000f, 1.0000f, 1.0000f, 0.8721f, 1.0000f, 1.0000f, 1.0000f, 0.8261f, 0.9771f, 1.0000f, + 1.0000f, 0.9081f, 0.9234f, 0.9183f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9306f, 0.9937f, 1.0000f, + 1.0000f, 0.3941f, 0.8581f, 0.9806f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9349f, 1.0000f, 1.0000f, + 1.0000f, 0.7669f, 0.9586f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7776f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8406f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9892f, 0.9839f, 0.9689f, 0.8773f, 0.6112f, 0.8610f, 0.9811f, 0.1716f, 0.5980f, 0.6238f, 0.9796f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9635f, 0.9762f, 0.8237f, 0.5187f, 0.7399f, 0.9753f, 1.0000f, 1.0000f, 0.6415f, 0.8449f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.6706f, 0.8765f, 0.9497f, 0.8511f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, + 1.0000f, 0.8141f, 0.9166f, 0.9857f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.7731f, 0.9543f, 1.0000f, 0.7228f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9998f, 0.9996f, + 1.0000f, 0.8978f, 1.0000f, 1.0000f, 0.1169f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9675f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0559f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9953f, 0.9512f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9868f, 0.9712f, + 1.0000f, 0.9316f, 0.9456f, 0.9603f, 1.0000f, 0.6553f, 0.9124f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, + 1.0000f, 0.9846f, 0.9239f, 0.9692f, 1.0000f, 0.8384f, 0.9969f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, + 1.0000f, 0.7380f, 0.9443f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9924f, 0.9377f, + 1.0000f, 0.8896f, 0.9823f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 0.9927f, 0.7805f, + 1.0000f, 0.7863f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9722f, 0.9835f, 0.9841f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9368f, 0.9725f, 0.8501f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9663f, 0.8040f, 0.8667f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9520f, 0.9372f, 0.9629f, + 1.0000f, 1.0000f, 0.9987f, 0.9999f, 0.9477f, 0.9923f, 0.9154f, 0.7834f, 0.9982f, 0.9920f, 0.9794f, 0.8363f, 1.0000f, 0.9982f, 0.9948f, 0.9899f, + 1.0000f, 0.9990f, 0.9975f, 1.0000f, 0.7086f, 0.9819f, 0.8756f, 1.0000f, 1.0000f, 0.9967f, 0.9189f, 1.0000f, 1.0000f, 0.9971f, 0.9960f, 0.8676f, + 1.0000f, 0.9981f, 0.9509f, 0.9413f, 1.0000f, 0.9842f, 0.9468f, 1.0000f, 1.0000f, 0.9946f, 0.9909f, 1.0000f, 1.0000f, 0.9944f, 0.8116f, 0.9130f, + 1.0000f, 0.9976f, 0.9907f, 0.2986f, 1.0000f, 0.7573f, 1.0000f, 1.0000f, 1.0000f, 0.8490f, 1.0000f, 1.0000f, 1.0000f, 0.9952f, 0.5879f, 1.0000f, + 1.0000f, 0.9978f, 0.8963f, 0.1264f, 1.0000f, 0.8747f, 1.0000f, 1.0000f, 1.0000f, 0.9681f, 1.0000f, 1.0000f, 1.0000f, 0.9660f, 0.8427f, 1.0000f, + 1.0000f, 0.9895f, 0.5337f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5668f, 1.0000f, 1.0000f, + 1.0000f, 0.9918f, 0.2925f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9094f, 1.0000f, 1.0000f, + 1.0000f, 0.8639f, 0.4569f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6444f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9985f, 0.9940f, 1.0000f, 0.9973f, 0.8351f, 0.9903f, 1.0000f, 0.9980f, 0.9326f, 0.9989f, 1.0000f, 1.0000f, 0.9933f, 0.8985f, + 1.0000f, 0.9943f, 0.9955f, 0.9873f, 1.0000f, 0.9745f, 0.7746f, 1.0000f, 1.0000f, 0.9938f, 0.9006f, 1.0000f, 1.0000f, 0.9945f, 0.9789f, 0.7974f, + 1.0000f, 0.9850f, 0.9524f, 0.2388f, 1.0000f, 0.9599f, 1.0000f, 1.0000f, 1.0000f, 0.9942f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.7127f, 1.0000f, + 1.0000f, 0.9773f, 0.7247f, 0.4198f, 1.0000f, 0.6892f, 1.0000f, 1.0000f, 1.0000f, 0.8571f, 1.0000f, 1.0000f, 1.0000f, 0.9382f, 1.0000f, 1.0000f, + 1.0000f, 0.9884f, 0.2172f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9642f, 1.0000f, 1.0000f, + 1.0000f, 0.8480f, 0.4434f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6269f, 1.0000f, 1.0000f, + 1.0000f, 0.9311f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2529f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9999f, 0.9981f, 0.9645f, 0.8911f, 0.9990f, 0.7919f, 1.0000f, 0.5031f, 0.9778f, 0.8992f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9970f, 0.9886f, 0.8417f, 0.0322f, 0.9281f, 0.9678f, 1.0000f, 1.0000f, 0.9706f, 0.9889f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9983f, + 1.0000f, 0.9950f, 0.7891f, 0.9206f, 0.7435f, 0.9142f, 1.0000f, 1.0000f, 1.0000f, 0.9861f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 1.0000f, + 1.0000f, 0.9780f, 0.2459f, 1.0000f, 0.0876f, 0.9764f, 1.0000f, 1.0000f, 1.0000f, 0.9928f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9815f, 0.7453f, 1.0000f, 0.1796f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 0.9993f, + 1.0000f, 0.5449f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 1.0000f, 0.9995f, + 1.0000f, 0.8888f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9974f, 1.0000f, + 1.0000f, 0.3223f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9991f, 0.9878f, + 1.0000f, 0.9952f, 0.9695f, 0.8856f, 1.0000f, 0.9703f, 0.8091f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9964f, + 1.0000f, 0.9864f, 0.9275f, 0.7715f, 1.0000f, 0.8799f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9983f, + 1.0000f, 0.9785f, 0.4700f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9949f, 0.9910f, + 1.0000f, 0.8658f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9977f, + 1.0000f, 0.9626f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9970f, 0.9804f, + 1.0000f, 0.3836f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9954f, 0.9930f, 0.5070f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9546f, 0.5412f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9831f, 0.8202f, 0.7305f, + 1.0000f, 0.9993f, 0.9321f, 0.7622f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7638f, 1.0000f, 1.0000f, + 1.0000f, 0.9906f, 0.9217f, 0.9698f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9345f, 1.0000f, 1.0000f, + 1.0000f, 0.0665f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.4784f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8694f, 0.8214f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, 1.0000f, + 1.0000f, 0.8295f, 0.9829f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7417f, 1.0000f, 1.0000f, 0.8178f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 1.0000f, 0.9996f, + 1.0000f, 0.9255f, 1.0000f, 1.0000f, 0.1357f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, 0.9965f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1629f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9919f, 0.9996f, 0.9966f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9967f, 0.9984f, 0.9616f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, 0.9464f, 0.7933f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9417f, 0.9748f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9027f, 0.8053f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8329f, 0.9992f, 1.0000f, + 1.0000f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9890f, 1.0000f, 0.9984f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 1.0000f, 0.9409f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8926f, 0.3509f, 0.9244f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7540f, 0.6579f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3105f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6958f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; + +const float percentile_table_12x12[2048] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6459f, 1.0000f, 0.9751f, 0.9422f, 0.8309f, 1.0000f, 0.9931f, 0.9934f, 0.5189f, 1.0000f, 0.9984f, 0.9983f, + 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.8017f, 0.9895f, 0.9892f, 0.9881f, 0.7254f, 0.9869f, 0.9932f, 0.9621f, 0.2345f, 1.0000f, 0.9979f, 0.9988f, + 1.0000f, 1.0000f, 0.9882f, 0.9996f, 0.7782f, 0.9961f, 0.9574f, 0.7435f, 0.5997f, 0.9965f, 0.9644f, 0.7057f, 0.8481f, 1.0000f, 0.9914f, 0.9132f, + 1.0000f, 1.0000f, 0.9990f, 0.9919f, 0.8255f, 0.9789f, 0.9227f, 0.6933f, 0.5375f, 0.9716f, 0.9361f, 0.6779f, 1.0000f, 0.9858f, 0.9781f, 0.9066f, + 1.0000f, 1.0000f, 0.9834f, 0.9545f, 0.7662f, 0.9394f, 0.6975f, 0.7216f, 0.8351f, 0.9755f, 0.7097f, 0.6513f, 1.0000f, 0.9863f, 0.9178f, 0.4660f, + 1.0000f, 0.9725f, 0.9933f, 0.9434f, 0.2471f, 0.9189f, 0.3612f, 0.9206f, 1.0000f, 0.9402f, 0.3160f, 0.9155f, 1.0000f, 0.9609f, 0.8537f, 0.4868f, + 1.0000f, 1.0000f, 0.9701f, 0.8698f, 0.3053f, 0.8945f, 0.1802f, 1.0000f, 1.0000f, 0.9097f, 0.1414f, 1.0000f, 1.0000f, 0.9735f, 0.5781f, 0.2594f, + 1.0000f, 0.9799f, 0.8628f, 0.5549f, 0.7235f, 0.6824f, 0.6996f, 1.0000f, 1.0000f, 0.6566f, 0.6802f, 1.0000f, 1.0000f, 0.9138f, 0.3107f, 0.6348f, + 1.0000f, 1.0000f, 1.0000f, 0.9960f, 0.7016f, 1.0000f, 0.9711f, 0.9184f, 0.8830f, 1.0000f, 0.9853f, 0.9378f, 0.6710f, 1.0000f, 0.9975f, 0.9957f, + 1.0000f, 1.0000f, 0.9975f, 0.9999f, 0.8723f, 0.9875f, 0.9486f, 0.9398f, 0.8210f, 0.9647f, 0.9783f, 0.9021f, 0.5149f, 1.0000f, 0.9980f, 0.9926f, + 1.0000f, 1.0000f, 0.9947f, 0.9888f, 0.8966f, 0.9873f, 0.9252f, 0.7117f, 0.6615f, 0.9718f, 0.9475f, 0.7137f, 0.8952f, 1.0000f, 0.9596f, 0.9339f, + 1.0000f, 0.9923f, 0.9870f, 0.8878f, 0.8637f, 0.9464f, 0.6891f, 0.7469f, 0.4040f, 0.9507f, 0.6756f, 0.6869f, 1.0000f, 0.9830f, 0.9704f, 0.5812f, + 1.0000f, 1.0000f, 0.9593f, 0.9167f, 0.8068f, 0.9558f, 0.5302f, 0.8806f, 0.8233f, 0.9825f, 0.4531f, 0.8915f, 1.0000f, 0.9739f, 0.8443f, 0.3467f, + 1.0000f, 0.9836f, 0.8757f, 0.5651f, 0.2714f, 0.7977f, 0.6291f, 1.0000f, 1.0000f, 0.8116f, 0.4268f, 1.0000f, 1.0000f, 0.9109f, 0.3660f, 0.6540f, + 1.0000f, 0.9921f, 0.9172f, 0.5515f, 0.5480f, 0.7737f, 0.5446f, 1.0000f, 1.0000f, 0.8341f, 0.3317f, 1.0000f, 1.0000f, 0.9161f, 0.2772f, 0.5265f, + 1.0000f, 0.9531f, 0.7273f, 0.2944f, 0.7452f, 0.4618f, 1.0000f, 1.0000f, 1.0000f, 0.3755f, 1.0000f, 1.0000f, 1.0000f, 0.8092f, 0.3851f, 1.0000f, + 1.0000f, 1.0000f, 0.9887f, 0.9982f, 0.9281f, 1.0000f, 0.9658f, 0.9352f, 0.1329f, 1.0000f, 0.9864f, 0.9410f, 0.5030f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9988f, 0.9984f, 0.6954f, 0.9479f, 0.8814f, 0.7157f, 0.2014f, 0.9811f, 0.9453f, 0.7796f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9809f, 0.9084f, 0.8663f, 0.9661f, 0.8030f, 0.6263f, 0.0965f, 0.9913f, 0.7895f, 0.5717f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9680f, 0.9757f, 0.9059f, 0.3993f, 0.9748f, 0.6663f, 0.8592f, 1.0000f, 0.9688f, 0.6912f, 0.7937f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9706f, 0.9639f, 0.5227f, 0.8500f, 0.9247f, 0.3368f, 1.0000f, 0.4827f, 0.9335f, 0.1946f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9561f, 0.8619f, 0.4909f, 0.0437f, 0.7752f, 0.8518f, 1.0000f, 1.0000f, 0.7347f, 0.7767f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.9677f, 0.5749f, 0.2886f, 0.7291f, 0.8372f, 1.0000f, 1.0000f, 1.0000f, 0.8681f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9996f, + 1.0000f, 0.9313f, 0.3265f, 0.6234f, 0.1063f, 0.2147f, 1.0000f, 1.0000f, 1.0000f, 0.1153f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9978f, 1.0000f, + 1.0000f, 1.0000f, 0.9856f, 0.9986f, 0.4990f, 1.0000f, 0.8413f, 0.8128f, 1.0000f, 1.0000f, 0.9348f, 0.8452f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9954f, 0.9803f, 0.4949f, 0.9457f, 0.9257f, 0.5339f, 1.0000f, 0.9872f, 0.9691f, 0.6591f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9721f, 0.9272f, 0.4087f, 0.9641f, 0.5875f, 0.7631f, 1.0000f, 0.9535f, 0.5843f, 0.6687f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, + 1.0000f, 0.9723f, 0.9445f, 0.6147f, 0.6206f, 0.8789f, 0.4703f, 1.0000f, 1.0000f, 0.9149f, 0.4444f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9890f, + 1.0000f, 0.9841f, 0.8610f, 0.4313f, 1.0000f, 0.8176f, 0.6117f, 1.0000f, 1.0000f, 0.8740f, 0.2408f, 1.0000f, 1.0000f, 1.0000f, 0.9986f, 0.9985f, + 1.0000f, 0.8994f, 0.4178f, 0.7486f, 1.0000f, 0.6431f, 1.0000f, 1.0000f, 1.0000f, 0.6404f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 0.9916f, + 1.0000f, 0.9300f, 0.2829f, 0.5584f, 1.0000f, 0.7417f, 1.0000f, 1.0000f, 1.0000f, 0.8298f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9963f, 0.9964f, + 1.0000f, 0.8244f, 0.4575f, 1.0000f, 1.0000f, 0.4744f, 1.0000f, 1.0000f, 1.0000f, 0.2214f, 1.0000f, 1.0000f, 1.0000f, 0.9944f, 0.9900f, 0.8838f, + 1.0000f, 0.9996f, 0.9997f, 0.9984f, 0.4786f, 0.9295f, 0.8862f, 0.9633f, 0.9490f, 0.9672f, 0.9200f, 0.9730f, 1.0000f, 0.9956f, 0.9946f, 0.9742f, + 1.0000f, 0.9999f, 0.9991f, 0.9603f, 0.5967f, 0.8870f, 0.9430f, 0.9650f, 1.0000f, 0.9322f, 0.9555f, 0.9787f, 1.0000f, 0.9815f, 0.9866f, 0.8893f, + 1.0000f, 0.9482f, 0.9813f, 0.9524f, 1.0000f, 0.8715f, 0.9805f, 1.0000f, 1.0000f, 0.8773f, 0.9766f, 1.0000f, 1.0000f, 0.7196f, 0.8930f, 0.9764f, + 1.0000f, 0.8959f, 0.9606f, 0.7825f, 1.0000f, 0.9460f, 1.0000f, 1.0000f, 1.0000f, 0.9630f, 1.0000f, 1.0000f, 1.0000f, 0.8383f, 0.9521f, 0.9948f, + 1.0000f, 0.8490f, 0.8140f, 0.9565f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7502f, 0.9386f, 1.0000f, + 1.0000f, 0.7810f, 0.9382f, 0.9636f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8320f, 1.0000f, 1.0000f, + 1.0000f, 0.2999f, 0.8646f, 0.9777f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7600f, 0.9696f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9997f, 0.9850f, 0.9027f, 0.5618f, 0.8055f, 0.9001f, 0.9974f, 0.9685f, 0.8509f, 0.8556f, 0.9959f, 1.0000f, 0.9441f, 0.9774f, 0.9762f, + 1.0000f, 0.9965f, 0.9693f, 0.9242f, 0.6376f, 0.8423f, 0.9666f, 0.9922f, 1.0000f, 0.8987f, 0.9669f, 0.9991f, 1.0000f, 0.9938f, 0.9528f, 0.9891f, + 1.0000f, 0.9612f, 0.7923f, 0.8574f, 1.0000f, 0.9237f, 1.0000f, 1.0000f, 1.0000f, 0.9344f, 1.0000f, 1.0000f, 1.0000f, 0.7535f, 0.9768f, 1.0000f, + 1.0000f, 0.9449f, 0.9374f, 0.9517f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9040f, 0.9955f, 1.0000f, + 1.0000f, 0.3213f, 0.8923f, 0.9708f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8765f, 1.0000f, 1.0000f, + 1.0000f, 0.7552f, 0.9548f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7839f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8706f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9918f, 0.9807f, 0.9627f, 0.8546f, 0.6176f, 0.8781f, 0.9819f, 0.0866f, 0.6733f, 0.8288f, 0.9937f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9744f, 0.9737f, 0.8199f, 0.3803f, 0.7519f, 0.9930f, 1.0000f, 1.0000f, 0.7615f, 0.9885f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.7365f, 0.9090f, 0.9793f, 0.8277f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8528f, 0.9568f, 0.9837f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9990f, 0.9999f, + 1.0000f, 0.7722f, 0.9414f, 1.0000f, 0.6847f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9977f, 0.9969f, + 1.0000f, 0.8885f, 1.0000f, 1.0000f, 0.0762f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 0.9624f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1243f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9920f, 0.9276f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9827f, 0.9500f, + 1.0000f, 0.9304f, 0.9600f, 0.9571f, 1.0000f, 0.6639f, 0.9078f, 1.0000f, 1.0000f, 0.7310f, 0.8980f, 1.0000f, 1.0000f, 1.0000f, 0.9989f, 1.0000f, + 1.0000f, 0.9896f, 0.9211f, 0.9675f, 1.0000f, 0.8362f, 0.9969f, 1.0000f, 1.0000f, 0.8004f, 0.9848f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, + 1.0000f, 0.7853f, 0.9779f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9941f, 0.9331f, + 1.0000f, 0.9120f, 0.9894f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9899f, 0.7867f, + 1.0000f, 0.8222f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9365f, 0.9746f, 0.9653f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9034f, 0.9538f, 0.7964f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9581f, 0.8043f, 0.8462f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9357f, 0.9493f, 0.9390f, + 1.0000f, 1.0000f, 0.9983f, 0.9987f, 0.9103f, 0.9995f, 0.9426f, 0.8973f, 0.9978f, 0.9971f, 0.9839f, 0.8152f, 1.0000f, 0.9945f, 0.9970f, 0.9795f, + 1.0000f, 0.9991f, 0.9998f, 0.9973f, 0.7647f, 0.9728f, 0.9114f, 1.0000f, 1.0000f, 0.9976f, 0.9216f, 0.9999f, 1.0000f, 0.9981f, 0.9844f, 0.8164f, + 1.0000f, 0.9999f, 0.9828f, 0.9541f, 1.0000f, 0.9797f, 0.9664f, 1.0000f, 1.0000f, 0.9785f, 0.9590f, 1.0000f, 1.0000f, 0.9980f, 0.7568f, 0.8854f, + 1.0000f, 0.9843f, 0.9832f, 0.4132f, 1.0000f, 0.8187f, 1.0000f, 1.0000f, 1.0000f, 0.8393f, 1.0000f, 1.0000f, 1.0000f, 0.9683f, 0.4401f, 1.0000f, + 1.0000f, 0.9952f, 0.8565f, 0.0654f, 1.0000f, 0.9144f, 1.0000f, 1.0000f, 1.0000f, 0.9126f, 1.0000f, 1.0000f, 1.0000f, 0.9867f, 0.7177f, 1.0000f, + 1.0000f, 0.9884f, 0.2654f, 0.9999f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.5906f, 1.0000f, 1.0000f, + 1.0000f, 0.9927f, 0.1728f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8672f, 1.0000f, 1.0000f, + 1.0000f, 0.8731f, 0.5070f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.3946f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 0.9986f, 1.0000f, 0.9929f, 0.9979f, 0.8655f, 0.9861f, 0.9990f, 0.9902f, 0.9262f, 0.9732f, 1.0000f, 0.9972f, 0.9943f, 0.8583f, + 1.0000f, 0.9939f, 0.9846f, 0.9698f, 0.9047f, 0.9772f, 0.7991f, 1.0000f, 1.0000f, 0.9948f, 0.8403f, 1.0000f, 1.0000f, 0.9967f, 0.9878f, 0.7328f, + 1.0000f, 0.9942f, 0.9587f, 0.3898f, 1.0000f, 0.9791f, 1.0000f, 1.0000f, 1.0000f, 0.9851f, 1.0000f, 1.0000f, 1.0000f, 0.9958f, 0.6087f, 1.0000f, + 1.0000f, 0.9406f, 0.7707f, 0.5410f, 1.0000f, 0.7881f, 1.0000f, 1.0000f, 1.0000f, 0.7077f, 1.0000f, 1.0000f, 1.0000f, 0.9286f, 1.0000f, 1.0000f, + 1.0000f, 0.9910f, 0.2280f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9511f, 1.0000f, 1.0000f, + 1.0000f, 0.8601f, 0.4223f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.2533f, 1.0000f, 1.0000f, + 1.0000f, 0.9821f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.2080f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9959f, 0.9713f, 0.9753f, 0.8471f, 0.9879f, 0.8331f, 1.0000f, 0.3708f, 0.9967f, 0.9014f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9966f, 0.9877f, 0.8689f, 0.0321f, 0.9577f, 0.9770f, 1.0000f, 1.0000f, 0.9817f, 0.9940f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9992f, + 1.0000f, 0.9928f, 0.8080f, 0.9497f, 0.7037f, 0.9222f, 1.0000f, 1.0000f, 1.0000f, 0.9859f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9615f, 0.5110f, 1.0000f, 0.0206f, 0.9907f, 1.0000f, 1.0000f, 1.0000f, 0.9801f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9973f, 0.9992f, + 1.0000f, 0.9369f, 0.7400f, 1.0000f, 0.1654f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9991f, 0.9962f, + 1.0000f, 0.5684f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 0.9909f, 1.0000f, + 1.0000f, 0.8938f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9968f, 0.9992f, + 1.0000f, 0.4488f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9987f, 0.9955f, 0.9898f, + 1.0000f, 0.9936f, 0.9855f, 0.8900f, 1.0000f, 0.9584f, 0.7950f, 1.0000f, 1.0000f, 0.9953f, 0.9072f, 1.0000f, 1.0000f, 1.0000f, 0.9997f, 1.0000f, + 1.0000f, 0.9905f, 0.9655f, 0.8266f, 1.0000f, 0.9232f, 1.0000f, 1.0000f, 1.0000f, 0.9504f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 0.9981f, 0.6320f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9998f, 1.0000f, + 1.0000f, 0.9008f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9823f, 0.9618f, + 1.0000f, 0.9195f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9988f, 0.9935f, 0.9468f, + 1.0000f, 0.3515f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9915f, 0.9904f, 0.3418f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9985f, 0.9471f, 0.4357f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9924f, 0.7909f, 0.6057f, + 1.0000f, 0.9971f, 0.9903f, 0.8822f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.7382f, 1.0000f, 1.0000f, + 1.0000f, 0.9989f, 0.9912f, 0.9759f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9326f, 1.0000f, 1.0000f, + 1.0000f, 0.1874f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.5936f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.9290f, 0.8748f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8104f, 0.9963f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 0.8433f, 1.0000f, 1.0000f, 0.7692f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, + 1.0000f, 0.9514f, 1.0000f, 1.0000f, 0.0546f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9993f, 1.0000f, 0.9949f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1497f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9976f, 0.9950f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, 0.9994f, 0.9418f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9908f, 0.9309f, 0.7584f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9951f, 0.9267f, 0.9318f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9437f, 0.7677f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8797f, 0.9994f, 1.0000f, + 1.0000f, 0.9982f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9994f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9995f, 0.9995f, 0.9551f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9053f, 0.3564f, 0.8908f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.8846f, 0.6486f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.1577f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.6027f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, +}; diff --git a/third_party/astcenc/Source/astc_pick_best_endpoint_format.cpp b/third_party/astcenc/Source/astc_pick_best_endpoint_format.cpp new file mode 100644 index 0000000000..0f6dffb6f5 --- /dev/null +++ b/third_party/astcenc/Source/astc_pick_best_endpoint_format.cpp @@ -0,0 +1,952 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions to pick the best ASTC endpoint format for a given block. + */ +/*----------------------------------------------------------------------------*/ +#include "astc_codec_internals.h" + +#ifdef DEBUG_PRINT_DIAGNOSTICS + #include +#endif + +#include + +// clamp an input value to [0,1]; Nan is turned into 0. +static inline float clamp01(float val) +{ + if (val > 1.0f) + val = 1.0f; + else if (val > 0.0f) + { + // deliberately empty; switching the order of calculation here will fail to handle 0. + } + else + val = 0.0f; + return val; +} + +/* + functions to determine, for a given partitioning, which color endpoint formats are the best to use. + + */ + + +// for a given partition, compute for every (integer-component-count, quantization-level) +// the color error. + + +static void compute_color_error_for_every_integer_count_and_quantization_level(int encode_hdr_rgb, // 1 = perform HDR encoding, 0 = perform LDR encoding. + int encode_hdr_alpha, int partition_index, const partition_info * pi, + const encoding_choice_errors * eci, // pointer to the structure for the CURRENT partition. + const endpoints * ep, float4 error_weightings[4], + // arrays to return results back through. + float best_error[21][4], int format_of_choice[21][4]) +{ + int i, j; + int partition_size = pi->texels_per_partition[partition_index]; + + static const float baseline_quant_error[21] = { + (65536.0f * 65536.0f / 18.0f), // 2 values, 1 step + (65536.0f * 65536.0f / 18.0f) / (2 * 2), // 3 values, 2 steps + (65536.0f * 65536.0f / 18.0f) / (3 * 3), // 4 values, 3 steps + (65536.0f * 65536.0f / 18.0f) / (4 * 4), // 5 values + (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) + }; + + float4 ep0 = ep->endpt0[partition_index]; + float4 ep1 = ep->endpt1[partition_index]; + + float ep0_max = MAX(MAX(ep0.x, ep0.y), ep0.z); + float ep0_min = MIN(MIN(ep0.x, ep0.y), ep0.z); + float ep1_max = MAX(MAX(ep1.x, ep1.y), ep1.z); + float ep1_min = MIN(MIN(ep1.x, ep1.y), ep1.z); + + ep0_min = MAX(ep0_min, 0.0f); + ep1_min = MAX(ep1_min, 0.0f); + ep0_max = MAX(ep0_max, 1e-10f); + ep1_max = MAX(ep1_max, 1e-10f); + + float4 error_weight = error_weightings[partition_index]; + + float error_weight_rgbsum = error_weight.x + error_weight.y + error_weight.z; + + 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 situation, + float4 ep0_range_error_high; + float4 ep1_range_error_high; + float4 ep0_range_error_low; + float4 ep1_range_error_low; + + ep0_range_error_high.x = MAX(0.0f, ep0.x - range_upper_limit_rgb); + ep0_range_error_high.y = MAX(0.0f, ep0.y - range_upper_limit_rgb); + ep0_range_error_high.z = MAX(0.0f, ep0.z - range_upper_limit_rgb); + ep0_range_error_high.w = MAX(0.0f, ep0.w - range_upper_limit_alpha); + ep1_range_error_high.x = MAX(0.0f, ep1.x - range_upper_limit_rgb); + ep1_range_error_high.y = MAX(0.0f, ep1.y - range_upper_limit_rgb); + ep1_range_error_high.z = MAX(0.0f, ep1.z - range_upper_limit_rgb); + ep1_range_error_high.w = MAX(0.0f, ep1.w - range_upper_limit_alpha); + + ep0_range_error_low.x = MIN(0.0f, ep0.x); + ep0_range_error_low.y = MIN(0.0f, ep0.y); + ep0_range_error_low.z = MIN(0.0f, ep0.z); + ep0_range_error_low.w = MIN(0.0f, ep0.w); + ep1_range_error_low.x = MIN(0.0f, ep1.x); + ep1_range_error_low.y = MIN(0.0f, ep1.y); + ep1_range_error_low.z = MIN(0.0f, ep1.z); + ep1_range_error_low.w = MIN(0.0f, ep1.w); + + float4 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 = dot(sum_range_error.xyz, error_weight.xyz) * 0.5f * partition_size; + float alpha_range_error = sum_range_error.w * error_weight.w * 0.5f * partition_size; + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : partition=%d\nrgb-error_wt=%f alpha_error_wt=%f\n", __func__, partition_index, error_weight_rgbsum, error_weight.w); + + printf("ep0 = %f %f %f %f\n", ep0.x, ep0.y, ep0.z, ep0.w); + printf("ep1 = %f %f %f %f\n", ep1.x, ep1.y, ep1.z, ep1.w); + + + printf("rgb_range_error = %f, alpha_range_error = %f\n", rgb_range_error, alpha_range_error); + + printf("rgb-luma-error: %f\n", eci->rgb_luma_error); + } + #endif + + if (encode_hdr_rgb) + { + + // collect some statistics + float af, cf; + if (ep1.x > ep1.y && ep1.x > ep1.z) + { + af = ep1.x; + cf = ep1.x - ep0.x; + } + else if (ep1.y > ep1.z) + { + af = ep1.y; + cf = ep1.y - ep0.y; + } + else + { + af = ep1.z; + cf = ep1.z - ep0.z; + } + + float bf = af - ep1_min; // estimate of color-component spread in high endpoint color + float3 prd = ep1.xyz - float3(cf, cf, cf); + float3 pdif = prd - ep0.xyz; + // estimate of color-component spread in low endpoint color + float df = MAX(MAX(fabs(pdif.x), fabs(pdif.y)), fabs(pdif.z)); + + int b = (int)bf; + int c = (int)cf; + int d = (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 = (ep1.x + ep1.y + ep1.z) * (1.0f / 3.0f); + float lum_low = (ep0.x + ep0.y + ep0.z) * (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 (i = 0; i < 8; i++) + { + best_error[i][3] = 1e30f; + format_of_choice[i][3] = encode_hdr_alpha ? FMT_HDR_RGBA : FMT_HDR_RGB_LDR_ALPHA; + best_error[i][2] = 1e30f; + format_of_choice[i][2] = FMT_HDR_RGB; + best_error[i][1] = 1e30f; + format_of_choice[i][1] = FMT_HDR_RGB_SCALE; + best_error[i][0] = 1e30f; + format_of_choice[i][0] = FMT_HDR_LUMINANCE_LARGE_RANGE; + } + + + for (i = 8; i < 21; i++) + { + // 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] * partition_size * 1.0f; + float rgb_quantization_error = error_weight_rgbsum * base_quant_error * 2.0f; + float alpha_quantization_error = error_weight.w * base_quant_error * 2.0f; + float rgba_quantization_error = rgb_quantization_error + alpha_quantization_error; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("rgba-quant = %f can_offset_encode=%d\n", rgba_quantization_error, eci->can_offset_encode); + #endif + + // for 8 integers, we have two encodings: one with HDR alpha and another one + // with LDR alpha. + + 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] = 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; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + for (j = 0; j < 4; j++) + { + printf("(hdr) quant-level=%d ints=%d format=%d error=%f\n", i, j, format_of_choice[i][j], best_error[i][j]); + } + } + #endif + } + } + + + else + { + for (i = 0; i < 4; i++) + { + best_error[i][3] = 1e30f; + best_error[i][2] = 1e30f; + best_error[i][1] = 1e30f; + best_error[i][0] = 1e30f; + + 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; + } + + + // pick among the available LDR endpoint modes + for (i = 4; i < 21; i++) + { + float base_quant_error = baseline_quant_error[i] * partition_size * 1.0f; + float rgb_quantization_error = error_weight_rgbsum * base_quant_error; + float alpha_quantization_error = error_weight.w * base_quant_error; + float rgba_quantization_error = rgb_quantization_error + alpha_quantization_error; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + printf("rgba-quant = %f can_offset_encode=%d\n", rgba_quantization_error, eci->can_offset_encode); + #endif + + // for 8 integers, the available encodings are: + // full LDR RGB-Alpha + float full_ldr_rgba_error = rgba_quantization_error; + if (eci->can_blue_contract) + full_ldr_rgba_error *= 0.625f; + if (eci->can_offset_encode && i <= 18) + full_ldr_rgba_error *= 0.5f; + full_ldr_rgba_error += rgb_range_error + alpha_range_error; + + best_error[i][3] = full_ldr_rgba_error; + format_of_choice[i][3] = FMT_RGBA; + + // for 6 integers, we have: + // - an LDR-RGB encoding + // - an RGBS + Alpha encoding (LDR) + + float full_ldr_rgb_error = rgb_quantization_error; + if (eci->can_blue_contract) + full_ldr_rgb_error *= 0.5f; + if (eci->can_offset_encode && i <= 18) + full_ldr_rgb_error *= 0.25f; + full_ldr_rgb_error += eci->alpha_drop_error + rgb_range_error; + + float rgbs_alpha_error = rgba_quantization_error + 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; + } + + + // for 4 integers, we have a Luminance-Alpha encoding and the RGBS encoding + float ldr_rgbs_error = rgb_quantization_error + eci->alpha_drop_error + eci->rgb_scale_error + rgb_range_error; + + float lum_alpha_error = rgba_quantization_error + eci->luminance_error + rgb_range_error + alpha_range_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; + } + + + // for 2 integers, we have a Luminance-encoding and an Alpha-encoding. + float luminance_error = rgb_quantization_error + eci->alpha_drop_error + eci->luminance_error + rgb_range_error; + + best_error[i][0] = luminance_error; + format_of_choice[i][0] = FMT_LUMINANCE; + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + for (j = 0; j < 4; j++) + { + printf(" (ldr) quant-level=%d ints=%d format=%d error=%f\n", i, j, format_of_choice[i][j], best_error[i][j]); + } + } + #endif + } + } +} + + + +// for 1 partition, find the best combination (one format + a quantization level) for a given bitcount + +static void one_partition_find_best_combination_for_bitcount(float combined_best_error[21][4], + int formats_of_choice[21][4], int bits_available, int *best_quantization_level, int *best_formats, float *error_of_best_combination) +{ + int i; + int best_integer_count = -1; + float best_integer_count_error = 1e20f; + for (i = 0; i < 4; i++) + { + // compute the quantization level for a given number of integers and a given number of bits. + int quantization_level = quantization_mode_table[i + 1][bits_available]; + if (quantization_level == -1) + continue; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all. + if (combined_best_error[quantization_level][i] < best_integer_count_error) + { + best_integer_count_error = combined_best_error[quantization_level][i]; + best_integer_count = i; + } + } + + int ql = quantization_mode_table[best_integer_count + 1][bits_available]; + + *best_quantization_level = ql; + *error_of_best_combination = best_integer_count_error; + if (ql >= 0) + *best_formats = formats_of_choice[ql][best_integer_count]; + else + *best_formats = FMT_LUMINANCE; + +} + + + +// for 2 partitions, find the best format combinations for every (quantization-mode, integer-count) combination + +static void two_partitions_find_best_combination_for_every_quantization_and_integer_count(float best_error[2][21][4], // indexed by (partition, quant-level, integer-pair-count-minus-1) + int format_of_choice[2][21][4], + float combined_best_error[21][7], // indexed by (quant-level, integer-pair-count-minus-2) + int formats_of_choice[21][7][2]) +{ + int i, j; + + for (i = 0; i < 21; i++) + for (j = 0; j < 7; j++) + combined_best_error[i][j] = 1e30f; + + int quant; + for (quant = 5; quant < 21; quant++) + { + for (i = 0; i < 4; i++) // integer-count for first endpoint-pair + { + for (j = 0; j < 4; j++) // integer-count for second endpoint-pair + { + int low2 = MIN(i, j); + int high2 = MAX(i, j); + if ((high2 - low2) > 1) + continue; + + int intcnt = i + j; + float errorterm = MIN(best_error[0][quant][i] + best_error[1][quant][j], 1e10f); + if (errorterm <= combined_best_error[quant][intcnt]) + { + combined_best_error[quant][intcnt] = errorterm; + formats_of_choice[quant][intcnt][0] = format_of_choice[0][quant][i]; + formats_of_choice[quant][intcnt][1] = format_of_choice[1][quant][j]; + } + } + } + } +} + + +// for 2 partitions, find the best combination (two formats + a quantization level) for a given bitcount + +static void two_partitions_find_best_combination_for_bitcount(float combined_best_error[21][7], + int formats_of_choice[21][7][2], + int bits_available, int *best_quantization_level, int *best_quantization_level_mod, int *best_formats, float *error_of_best_combination) +{ + int i; + + int best_integer_count = 0; + float best_integer_count_error = 1e20f; + int integer_count; + + for (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 quantization_level = quantization_mode_table[integer_count][bits_available]; + if (quantization_level == -1) + break; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all. + float integer_count_error = combined_best_error[quantization_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 = quantization_mode_table[best_integer_count][bits_available]; + int ql_mod = quantization_mode_table[best_integer_count][bits_available + 2]; + + *best_quantization_level = ql; + *best_quantization_level_mod = ql_mod; + *error_of_best_combination = best_integer_count_error; + if (ql >= 0) + { + for (i = 0; i < 2; i++) + best_formats[i] = formats_of_choice[ql][best_integer_count - 2][i]; + } + else + { + for (i = 0; i < 2; i++) + best_formats[i] = FMT_LUMINANCE; + } +} + + + + +// for 3 partitions, find the best format combinations for every (quantization-mode, integer-count) combination + +static void three_partitions_find_best_combination_for_every_quantization_and_integer_count(float best_error[3][21][4], // indexed by (partition, quant-level, integer-count) + int format_of_choice[3][21][4], float combined_best_error[21][10], int formats_of_choice[21][10][3]) +{ + int i, j, k; + + for (i = 0; i < 21; i++) + for (j = 0; j < 10; j++) + combined_best_error[i][j] = 1e30f; + + int quant; + for (quant = 5; quant < 21; quant++) + { + for (i = 0; i < 4; i++) // integer-count for first endpoint-pair + { + for (j = 0; j < 4; j++) // integer-count for second endpoint-pair + { + int low2 = MIN(i, j); + int high2 = MAX(i, j); + if ((high2 - low2) > 1) + continue; + for (k = 0; k < 4; k++) // integer-count for third endpoint-pair + { + int low3 = MIN(k, low2); + int high3 = MAX(k, high2); + if ((high3 - low3) > 1) + continue; + + int intcnt = i + j + k; + float errorterm = MIN(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k], 1e10f); + if (errorterm <= combined_best_error[quant][intcnt]) + { + combined_best_error[quant][intcnt] = errorterm; + formats_of_choice[quant][intcnt][0] = format_of_choice[0][quant][i]; + formats_of_choice[quant][intcnt][1] = format_of_choice[1][quant][j]; + formats_of_choice[quant][intcnt][2] = format_of_choice[2][quant][k]; + } + } + } + } + } +} + + +// for 3 partitions, find the best combination (three formats + a quantization level) for a given bitcount + +static void three_partitions_find_best_combination_for_bitcount(float combined_best_error[21][10], + int formats_of_choice[21][10][3], + int bits_available, int *best_quantization_level, int *best_quantization_level_mod, int *best_formats, float *error_of_best_combination) +{ + int i; + + int best_integer_count = 0; + float best_integer_count_error = 1e20f; + int integer_count; + + for (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 quantization_level = quantization_mode_table[integer_count][bits_available]; + if (quantization_level == -1) + break; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all. + float integer_count_error = combined_best_error[quantization_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 = quantization_mode_table[best_integer_count][bits_available]; + int ql_mod = quantization_mode_table[best_integer_count][bits_available + 5]; + + *best_quantization_level = ql; + *best_quantization_level_mod = ql_mod; + *error_of_best_combination = best_integer_count_error; + if (ql >= 0) + { + for (i = 0; i < 3; i++) + best_formats[i] = formats_of_choice[ql][best_integer_count - 3][i]; + } + else + { + for (i = 0; i < 3; i++) + best_formats[i] = FMT_LUMINANCE; + } +} + + + + +// for 4 partitions, find the best format combinations for every (quantization-mode, integer-count) combination + +static void four_partitions_find_best_combination_for_every_quantization_and_integer_count(float best_error[4][21][4], // indexed by (partition, quant-level, integer-count) + int format_of_choice[4][21][4], float combined_best_error[21][13], int formats_of_choice[21][13][4]) +{ + int i, j, k, l; + + for (i = 0; i < 21; i++) + for (j = 0; j < 13; j++) + combined_best_error[i][j] = 1e30f; + + int quant; + for (quant = 5; quant < 21; quant++) + { + for (i = 0; i < 4; i++) // integer-count for first endpoint-pair + { + for (j = 0; j < 4; j++) // integer-count for second endpoint-pair + { + int low2 = MIN(i, j); + int high2 = MAX(i, j); + if ((high2 - low2) > 1) + continue; + for (k = 0; k < 4; k++) // integer-count for third endpoint-pair + { + int low3 = MIN(k, low2); + int high3 = MAX(k, high2); + if ((high3 - low3) > 1) + continue; + for (l = 0; l < 4; l++) // integer-count for fourth endpoint-pair + { + int low4 = MIN(l, low3); + int high4 = MAX(l, high3); + if ((high4 - low4) > 1) + continue; + + int intcnt = i + j + k + l; + float errorterm = MIN(best_error[0][quant][i] + best_error[1][quant][j] + best_error[2][quant][k] + best_error[3][quant][l], 1e10f); + if (errorterm <= combined_best_error[quant][intcnt]) + { + combined_best_error[quant][intcnt] = errorterm; + formats_of_choice[quant][intcnt][0] = format_of_choice[0][quant][i]; + formats_of_choice[quant][intcnt][1] = format_of_choice[1][quant][j]; + formats_of_choice[quant][intcnt][2] = format_of_choice[2][quant][k]; + formats_of_choice[quant][intcnt][3] = format_of_choice[3][quant][l]; + } + } + } + } + } + } +} + + + + + + +// for 4 partitions, find the best combination (four formats + a quantization level) for a given bitcount + +static void four_partitions_find_best_combination_for_bitcount(float combined_best_error[21][13], + int formats_of_choice[21][13][4], + int bits_available, int *best_quantization_level, int *best_quantization_level_mod, int *best_formats, float *error_of_best_combination) +{ + int i; + int best_integer_count = 0; + float best_integer_count_error = 1e20f; + int integer_count; + + for (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 quantization_level = quantization_mode_table[integer_count][bits_available]; + if (quantization_level == -1) + break; // used to indicate the case where we don't have enough bits to represent a given endpoint format at all. + float integer_count_error = combined_best_error[quantization_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 = quantization_mode_table[best_integer_count][bits_available]; + int ql_mod = quantization_mode_table[best_integer_count][bits_available + 8]; + + *best_quantization_level = ql; + *best_quantization_level_mod = ql_mod; + *error_of_best_combination = best_integer_count_error; + if (ql >= 0) + { + for (i = 0; i < 4; i++) + best_formats[i] = formats_of_choice[ql][best_integer_count - 4][i]; + } + else + { + for (i = 0; i < 4; i++) + best_formats[i] = FMT_LUMINANCE; + } +} + + + +/* + The determine_optimal_set_of_endpoint_formats_to_use() function. + + It identifies, for each mode, which set of color endpoint encodings + produces the best overall result. It then reports back which 4 modes + look best, along with the ideal color encoding combination for each. + + It takes as input: + a partitioning an imageblock, + a set of color endpoints. + for each mode, the number of bits available for color encoding and the error incurred by quantization. + in case of 2 plane of weights, a specifier for which color component to use for the second plane of weights. + + It delivers as output for each of the 4 selected modes: + format specifier + for each partition + quantization level to use + modified quantization level to use + (when all format specifiers are equal) + */ + +void determine_optimal_set_of_endpoint_formats_to_use(int xdim, int ydim, int zdim, + const partition_info * pt, const imageblock * blk, const error_weight_block * ewb, + const endpoints * ep, + int separate_component, // separate color component for 2-plane mode; -1 for single-plane mode + // bitcounts and errors computed for the various quantization methods + const int *qwt_bitcounts, const float *qwt_errors, + // output data + int partition_format_specifiers[4][4], int quantized_weight[4], + int quantization_level[4], int quantization_level_mod[4]) +{ + int i, j; + int partition_count = pt->partition_count; + + int encode_hdr_rgb = blk->rgb_lns[0]; + int encode_hdr_alpha = blk->alpha_lns[0]; + + + // call a helper function to 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[4]; + compute_encoding_choice_errors(xdim, ydim, zdim, blk, pt, ewb, separate_component, eci); + + // for each partition, compute the error weights to apply for that partition. + float4 error_weightings[4]; + float4 dummied_color_scalefactors[4]; // only used to receive data + compute_partition_error_color_weightings(xdim, ydim, zdim, ewb, pt, error_weightings, dummied_color_scalefactors); + + + float best_error[4][21][4]; + int format_of_choice[4][21][4]; + for (i = 0; i < partition_count; i++) + compute_color_error_for_every_integer_count_and_quantization_level(encode_hdr_rgb, encode_hdr_alpha, i, pt, &(eci[i]), ep, error_weightings, best_error[i], format_of_choice[i]); + + float errors_of_best_combination[MAX_WEIGHT_MODES]; + int best_quantization_levels[MAX_WEIGHT_MODES]; + int best_quantization_levels_mod[MAX_WEIGHT_MODES]; + int best_ep_formats[MAX_WEIGHT_MODES][4]; + + // code for the case where the block contains 1 partition + if (partition_count == 1) + { + int best_quantization_level; + int best_format; + float error_of_best_combination; + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (qwt_errors[i] >= 1e29f) + { + errors_of_best_combination[i] = 1e30f; + continue; + } + + one_partition_find_best_combination_for_bitcount(best_error[0], format_of_choice[0], qwt_bitcounts[i], &best_quantization_level, &best_format, &error_of_best_combination); + error_of_best_combination += qwt_errors[i]; + + errors_of_best_combination[i] = error_of_best_combination; + best_quantization_levels[i] = best_quantization_level; + best_quantization_levels_mod[i] = best_quantization_level; + best_ep_formats[i][0] = best_format; + } + } + + // code for the case where the block contains 2 partitions + else if (partition_count == 2) + { + int best_quantization_level; + int best_quantization_level_mod; + int best_formats[2]; + float error_of_best_combination; + + float combined_best_error[21][7]; + int 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); + + + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (qwt_errors[i] >= 1e29f) + { + errors_of_best_combination[i] = 1e30f; + continue; + } + + two_partitions_find_best_combination_for_bitcount(combined_best_error, formats_of_choice, qwt_bitcounts[i], + &best_quantization_level, &best_quantization_level_mod, best_formats, &error_of_best_combination); + + error_of_best_combination += qwt_errors[i]; + + errors_of_best_combination[i] = error_of_best_combination; + best_quantization_levels[i] = best_quantization_level; + best_quantization_levels_mod[i] = best_quantization_level_mod; + best_ep_formats[i][0] = best_formats[0]; + best_ep_formats[i][1] = best_formats[1]; + } + } + + // code for the case where the block contains 3 partitions + else if (partition_count == 3) + { + int best_quantization_level; + int best_quantization_level_mod; + int best_formats[3]; + float error_of_best_combination; + + float combined_best_error[21][10]; + int 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); + + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (qwt_errors[i] >= 1e29f) + { + errors_of_best_combination[i] = 1e30f; + continue; + } + + three_partitions_find_best_combination_for_bitcount(combined_best_error, + formats_of_choice, qwt_bitcounts[i], &best_quantization_level, &best_quantization_level_mod, best_formats, &error_of_best_combination); + error_of_best_combination += qwt_errors[i]; + + errors_of_best_combination[i] = error_of_best_combination; + best_quantization_levels[i] = best_quantization_level; + best_quantization_levels_mod[i] = best_quantization_level_mod; + best_ep_formats[i][0] = best_formats[0]; + best_ep_formats[i][1] = best_formats[1]; + best_ep_formats[i][2] = best_formats[2]; + } + } + + // code for the case where the block contains 4 partitions + else if (partition_count == 4) + { + int best_quantization_level; + int best_quantization_level_mod; + int best_formats[4]; + float error_of_best_combination; + + float combined_best_error[21][13]; + int 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); + + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (qwt_errors[i] >= 1e29f) + { + errors_of_best_combination[i] = 1e30f; + continue; + } + four_partitions_find_best_combination_for_bitcount(combined_best_error, + formats_of_choice, qwt_bitcounts[i], &best_quantization_level, &best_quantization_level_mod, best_formats, &error_of_best_combination); + error_of_best_combination += qwt_errors[i]; + + errors_of_best_combination[i] = error_of_best_combination; + best_quantization_levels[i] = best_quantization_level; + best_quantization_levels_mod[i] = best_quantization_level_mod; + best_ep_formats[i][0] = best_formats[0]; + best_ep_formats[i][1] = best_formats[1]; + best_ep_formats[i][2] = best_formats[2]; + best_ep_formats[i][3] = best_formats[3]; + } + } + + // finally, go through the results and pick the 4 best-looking modes. + + int best_error_weights[4]; + + for (i = 0; i < 4; i++) + { + float best_ep_error = 1e30f; + int best_error_index = -1; + for (j = 0; j < MAX_WEIGHT_MODES; j++) + { + if (errors_of_best_combination[j] < best_ep_error && best_quantization_levels[j] >= 5) + { + best_ep_error = errors_of_best_combination[j]; + best_error_index = j; + } + } + best_error_weights[i] = best_error_index; + + if(best_error_index >= 0) + { + errors_of_best_combination[best_error_index] = 1e30f; + } + } + + for (i = 0; i < 4; i++) + { + quantized_weight[i] = best_error_weights[i]; + if (quantized_weight[i] >= 0) + { + quantization_level[i] = best_quantization_levels[best_error_weights[i]]; + quantization_level_mod[i] = best_quantization_levels_mod[best_error_weights[i]]; + for (j = 0; j < partition_count; j++) + { + partition_format_specifiers[i][j] = best_ep_formats[best_error_weights[i]][j]; + } + } + } +} diff --git a/third_party/astcenc/Source/astc_quantization.cpp b/third_party/astcenc/Source/astc_quantization.cpp new file mode 100644 index 0000000000..183c5a334a --- /dev/null +++ b/third_party/astcenc/Source/astc_quantization.cpp @@ -0,0 +1,558 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions and data table related to data quantization in ASTC. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +const uint8_t color_quantization_tables[21][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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + }, + { + 0, 0, 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, + }, +}; + + +const uint8_t color_unquantization_tables[21][256] = { + { + 0, 255, + }, + { + 0, 128, 255, + }, + { + 0, 85, 170, 255, + }, + { + 0, 64, 128, 192, 255, + }, + { + 0, 255, 51, 204, 102, 153, + }, + { + 0, 36, 73, 109, 146, 182, 219, 255, + }, + { + 0, 255, 28, 227, 56, 199, 84, 171, 113, 142, + }, + { + 0, 255, 69, 186, 23, 232, 92, 163, 46, 209, 116, 139, + }, + { + 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255, + }, + { + 0, 255, 67, 188, 13, 242, 80, 175, 27, 228, 94, 161, 40, 215, 107, 148, + 54, 201, 121, 134, + }, + { + 0, 255, 33, 222, 66, 189, 99, 156, 11, 244, 44, 211, 77, 178, 110, 145, + 22, 233, 55, 200, 88, 167, 121, 134, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, + { + 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, + }, +}; + +// quantization_mode_table[integercount/2][bits] gives +// us the quantization level for a given integer count and number of bits that +// the integer may fit into. This is needed for color decoding, +// and for the color encoding. +int quantization_mode_table[17][128]; + +void build_quantization_mode_table(void) +{ + int i, j; + for (i = 0; i <= 16; i++) + for (j = 0; j < 128; j++) + quantization_mode_table[i][j] = -1; + + for (i = 0; i < 21; i++) + for (j = 1; j <= 16; j++) + { + int p = compute_ise_bitcount(2 * j, (quantization_method) i); + if (p < 128) + quantization_mode_table[j][p] = i; + } + for (i = 0; i <= 16; i++) + { + int largest_value_so_far = -1; + for (j = 0; j < 128; j++) + { + if (quantization_mode_table[i][j] > largest_value_so_far) + largest_value_so_far = quantization_mode_table[i][j]; + else + quantization_mode_table[i][j] = largest_value_so_far; + } + } +} diff --git a/third_party/astcenc/Source/astc_stb_tga.cpp b/third_party/astcenc/Source/astc_stb_tga.cpp new file mode 100644 index 0000000000..70818afa49 --- /dev/null +++ b/third_party/astcenc/Source/astc_stb_tga.cpp @@ -0,0 +1,595 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions for loading/storing TGA files and the file types + * accessible through STB. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include "softfloat.h" +#include +#include + +#define STBI_HEADER_FILE_ONLY +#include + +astc_codec_image * load_image_with_stb(const char *filename, int padding, int *result) +{ + int xsize, ysize; + int components; + + int y_flip = 1; + int x, y; + + astc_codec_image *astc_img = NULL; + + if (stbi_is_hdr(filename)) + { + float *image = stbi_loadf(filename, &xsize, &ysize, &components, STBI_rgb_alpha); + + if (image != NULL) + { + astc_img = allocate_image(16, xsize, ysize, 1, padding); + for (y = 0; y < ysize; y++) + { + int y_dst = y + padding; + int y_src = y_flip ? (ysize - y - 1) : y; + float *src = image + 4 * xsize * y_src; + + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata16[0][y_dst][4 * x_dst] = float_to_sf16(src[4 * x], SF_NEARESTEVEN); + astc_img->imagedata16[0][y_dst][4 * x_dst + 1] = float_to_sf16(src[4 * x + 1], SF_NEARESTEVEN); + astc_img->imagedata16[0][y_dst][4 * x_dst + 2] = float_to_sf16(src[4 * x + 2], SF_NEARESTEVEN); + astc_img->imagedata16[0][y_dst][4 * x_dst + 3] = float_to_sf16(src[4 * x + 3], SF_NEARESTEVEN); + } + } + stbi_image_free(image); + fill_image_padding_area(astc_img); + *result = components + 0x80; + return astc_img; + } + } + else + { + stbi_uc *image = stbi_load(filename, &xsize, &ysize, &components, STBI_rgb_alpha); + + uint8_t *imageptr = (uint8_t *) image; + + if (image != NULL) + { + astc_img = allocate_image(8, xsize, ysize, 1, padding); + for (y = 0; y < ysize; y++) + { + int y_dst = y + padding; + int y_src = y_flip ? (ysize - y - 1) : y; + uint8_t *src = imageptr + 4 * xsize * y_src; + + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata8[0][y_dst][4 * x_dst] = src[4 * x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 1] = src[4 * x + 1]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 2] = src[4 * x + 2]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 3] = src[4 * x + 3]; + } + } + stbi_image_free(image); + fill_image_padding_area(astc_img); + *result = components; + return astc_img; + } + } + + // if we haven't returned, it's because we failed to load the file. + printf("Failed to load image %s\nReason: %s\n", filename, stbi_failure_reason()); + + *result = -1; + return NULL; +} + + + + + + + +/* + given a TGA filename, read in a TGA file and create test-vectors from it. +*/ + +struct tga_header +{ + uint8_t identsize; + uint8_t colormaptype; + uint8_t imagetype; + uint8_t dummied[5]; + uint16_t xstart; + uint16_t ystart; + uint16_t xsize; + uint16_t ysize; + uint8_t bitsperpixel; + uint8_t descriptor; +}; + + +enum tga_descriptor +{ + TGA_DESCRIPTOR_XFLIP = 0x10, + TGA_DESCRIPTOR_YFLIP = 0x20, +}; + +enum tga_type +{ + TGA_COLORMAP_NONE = 0x00, + /* other color map type codes are reserved */ + + TGA_IMAGETYPE_NONE = 0, /* no image data */ + TGA_IMAGETYPE_PSEUDOCOLOR = 1, /* color-mapped image */ + TGA_IMAGETYPE_TRUECOLOR = 2, /* true-color image */ + TGA_IMAGETYPE_GREYSCALE = 3, /* true-color single channel */ + TGA_IMAGETYPE_RLE_PSEUDOCOLOR = 9, /* RLE color-mapped image */ + TGA_IMAGETYPE_RLE_TRUECOLOR = 10, /* RLE true color */ + TGA_IMAGETYPE_RLE_GREYSCALE = 11, /* RLE true grey */ + + HTGA_IMAGETYPE_TRUECOLOR = 0x82, + HTGA_IMAGETYPE_GREYSCALE = 0x83, +}; + +enum tga_errors +{ + TGA_ERROR_OPEN = -1, /* error opening file */ + TGA_ERROR_READ = -2, /* error reading file */ + TGA_ERROR_COLORMAP = -3, /* file has a colormap (not supported) */ + TGA_ERROR_RLE = -4, /* file is run-length encoded (not supported) */ + TGA_ERROR_FORMAT = -5, /* file has an unsupported pixel format */ + TGA_ERROR_LAYOUT = -6 /* file layout unsupported (right-to-left flipped) */ +}; + + +/* + return: if positive number, then the number is #components in the image + 1=Grayscale 2=Grayscale+Alpha 3=RGB 4=RGB+Alpha + add 0x80 if the file was in fact a HTGA file with HDR content. + + if negative number, then what went wrong + -1=failed to open file + -2=failed to read data + -3=failed to load image because it has a colormap + -4=failed to load image because it is RLE-encoded + -5=failed to load image because it has an unsupported pixel type + -6=failed to load image because it is flipped in the x dimension +*/ + +astc_codec_image *load_tga_image(const char *tga_filename, int padding, int *result) +{ + int x, y; + int i; + + int y_flip; + + FILE *f = fopen(tga_filename, "rb"); + if (!f) + { + *result = TGA_ERROR_OPEN; + return NULL; + } + + tga_header hdr; + size_t bytes_read = fread(&hdr, 1, 18, f); + if (bytes_read != 18) + { + fclose(f); + *result = TGA_ERROR_READ; + return NULL; + } + if (hdr.colormaptype != 0) + { + fclose(f); + *result = TGA_ERROR_COLORMAP; + return NULL; + } + + // do a quick test for RLE-pictures so that we reject them + if (hdr.imagetype == TGA_IMAGETYPE_RLE_TRUECOLOR || hdr.imagetype == TGA_IMAGETYPE_RLE_PSEUDOCOLOR || hdr.imagetype == TGA_IMAGETYPE_RLE_GREYSCALE) + { + fclose(f); + printf("TGA image %s is RLE-encoded; only uncompressed TGAs are supported.\n", tga_filename); + *result = TGA_ERROR_RLE; + return NULL; + } + + // Check for x flip (rare, unsupported) and y flip (supported) + if (hdr.descriptor & TGA_DESCRIPTOR_XFLIP) + { + fclose(f); + *result = TGA_ERROR_LAYOUT; + return NULL; + } + if (hdr.descriptor & TGA_DESCRIPTOR_YFLIP) + y_flip = 1; + else + y_flip = 0; + + + // support 4 formats (non-RLE only): + // 8-bit grayscale + // 8-bit grayscale + 8-bit alpha + // RGB 8:8:8 + // RGBA 8:8:8:8 + + if (!(hdr.imagetype == TGA_IMAGETYPE_TRUECOLOR && hdr.bitsperpixel == 32) + && !(hdr.imagetype == TGA_IMAGETYPE_TRUECOLOR && hdr.bitsperpixel == 24) + && !(hdr.imagetype == TGA_IMAGETYPE_GREYSCALE && hdr.bitsperpixel == 16) + && !(hdr.imagetype == TGA_IMAGETYPE_GREYSCALE && hdr.bitsperpixel == 8) + && !(hdr.imagetype == HTGA_IMAGETYPE_TRUECOLOR && hdr.bitsperpixel == 64) + && !(hdr.imagetype == HTGA_IMAGETYPE_TRUECOLOR && hdr.bitsperpixel == 48) + && !(hdr.imagetype == HTGA_IMAGETYPE_GREYSCALE && hdr.bitsperpixel == 32) && !(hdr.imagetype == HTGA_IMAGETYPE_GREYSCALE && hdr.bitsperpixel == 16)) + { + fclose(f); + *result = TGA_ERROR_FORMAT; + return NULL; + } + + if (hdr.identsize != 0) // skip ID field if it present. + fseek(f, hdr.identsize, SEEK_CUR); + + int bytesperpixel = hdr.bitsperpixel / 8; + + int bitness = (hdr.imagetype >= 0x80) ? 16 : 8; + + + // OK, it seems we have a legit TGA or HTGA file of a format we understand. + // Now, let's read it. + + size_t bytestoread = 0; + uint8_t **row_pointers8 = NULL; + uint16_t **row_pointers16 = NULL; + if (bitness == 8) + { + row_pointers8 = new uint8_t *[hdr.ysize]; + row_pointers8[0] = new uint8_t[hdr.xsize * hdr.ysize * bytesperpixel]; + for (i = 1; i < hdr.ysize; i++) + row_pointers8[i] = row_pointers8[0] + hdr.xsize * bytesperpixel * i; + bytestoread = hdr.xsize * hdr.ysize * bytesperpixel; + bytes_read = fread(row_pointers8[0], 1, bytestoread, f); + } + else if (bitness == 16) + { + row_pointers16 = new uint16_t *[hdr.ysize]; + row_pointers16[0] = new uint16_t[hdr.xsize * hdr.ysize * (bytesperpixel / 2)]; + for (i = 1; i < hdr.ysize; i++) + row_pointers16[i] = row_pointers16[0] + hdr.xsize * (bytesperpixel / 2) * i; + bytestoread = hdr.xsize * hdr.ysize * bytesperpixel; + bytes_read = fread(row_pointers16[0], 1, bytestoread, f); + } + + fclose(f); + if (bytes_read != bytestoread) + { + if (row_pointers8) + { + delete[]row_pointers8[0]; + delete[]row_pointers8; + } + if (row_pointers16) + { + delete[]row_pointers16[0]; + delete[]row_pointers16; + } + *result = -2; + return NULL; + } + + + + // OK, at this point, we can expand the image data to RGBA. + int ysize = hdr.ysize; + int xsize = hdr.xsize; + + astc_codec_image *astc_img = allocate_image(bitness, xsize, ysize, 1, padding); + + int retval; + + if (bitness == 8) + { + for (y = 0; y < ysize; y++) + { + int y_dst = y + padding; + int y_src = y_flip ? (ysize - y - 1) : y; + + switch (bytesperpixel) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata8[0][y_dst][4 * x_dst] = row_pointers8[y_src][x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 1] = row_pointers8[y_src][x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 2] = row_pointers8[y_src][x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 3] = 0xFF; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata8[0][y_dst][4 * x_dst] = row_pointers8[y_src][2 * x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 1] = row_pointers8[y_src][2 * x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 2] = row_pointers8[y_src][2 * x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 3] = row_pointers8[y_src][2 * x + 1]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata8[0][y_dst][4 * x_dst] = row_pointers8[y_src][3 * x + 2]; // TGA uses BGR, we use RGB + astc_img->imagedata8[0][y_dst][4 * x_dst + 1] = row_pointers8[y_src][3 * x + 1]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 2] = row_pointers8[y_src][3 * x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 3] = 0xFF; + } + break; + case 4: // four-component, treated as RGBA + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata8[0][y_dst][4 * x_dst] = row_pointers8[y_src][4 * x + 2]; // TGA uses BGR, we use RGB + astc_img->imagedata8[0][y_dst][4 * x_dst + 1] = row_pointers8[y_src][4 * x + 1]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 2] = row_pointers8[y_src][4 * x]; + astc_img->imagedata8[0][y_dst][4 * x_dst + 3] = row_pointers8[y_src][4 * x + 3]; + } + break; + } + } + delete[]row_pointers8[0]; + delete[]row_pointers8; + retval = bytesperpixel; + } + else // if( bitness == 16 ) + { + for (y = 0; y < ysize; y++) + { + int y_dst = y + padding; + int y_src = y_flip ? (ysize - y - 1) : y; + + switch (bytesperpixel) + { + case 2: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata16[0][y_dst][4 * x_dst] = row_pointers16[y_src][x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 1] = row_pointers16[y_src][x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 2] = row_pointers16[y_src][x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 3] = 0x3C00; + } + break; + case 4: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata16[0][y_dst][4 * x_dst] = row_pointers16[y_src][2 * x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 1] = row_pointers16[y_src][2 * x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 2] = row_pointers16[y_src][2 * x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 3] = row_pointers16[y_src][2 * x + 1]; + } + break; + case 6: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata16[0][y_dst][4 * x_dst] = row_pointers16[y_src][3 * x + 2]; // TGA uses BGR, we use RGB + astc_img->imagedata16[0][y_dst][4 * x_dst + 1] = row_pointers16[y_src][3 * x + 1]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 2] = row_pointers16[y_src][3 * x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 3] = 0x3C00; + } + break; + case 8: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + int x_dst = x + padding; + astc_img->imagedata16[0][y_dst][4 * x_dst] = row_pointers16[y_src][4 * x + 2]; // TGA uses BGR, we use RGB + astc_img->imagedata16[0][y_dst][4 * x_dst + 1] = row_pointers16[y_src][4 * x + 1]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 2] = row_pointers16[y_src][4 * x]; + astc_img->imagedata16[0][y_dst][4 * x_dst + 3] = row_pointers16[y_src][4 * x + 3]; + } + break; + } + } + delete[]row_pointers16[0]; + delete[]row_pointers16; + retval = (bytesperpixel / 2) + 0x80; + } + + fill_image_padding_area(astc_img); + *result = retval; + return astc_img; +} + + + + +/* + returns -1 if any problems arose when writing the file, else the number of color channels it chose to write. + */ +int store_tga_image(const astc_codec_image * img, const char *tga_filename, int bitness) +{ + int x, y; + int i; + + int xsize = img->xsize; + int ysize = img->ysize; + + // first scan through the image data + // to determine how many color channels the image has. + int image_channels = determine_image_channels(img); + + // construct a header + tga_header hdr; + hdr.identsize = 0; + hdr.colormaptype = 0; + hdr.imagetype = image_channels >= 3 ? 2 : 3; + if (bitness == 16) + hdr.imagetype |= 0x80; + + for (i = 0; i < 5; i++) + hdr.dummied[i] = 0; + hdr.xstart = 0; + hdr.ystart = 0; + hdr.xsize = xsize; + hdr.ysize = ysize; + hdr.bitsperpixel = image_channels * bitness; + hdr.descriptor = 0; + + int bytesperpixel = image_channels; + + // construct image data to write + + uint8_t **row_pointers8 = NULL; + uint16_t **row_pointers16 = NULL; + if (bitness == 8) + { + row_pointers8 = new uint8_t *[hdr.ysize]; + row_pointers8[0] = new uint8_t[hdr.xsize * hdr.ysize * bytesperpixel]; + for (i = 1; i < hdr.ysize; i++) + row_pointers8[i] = row_pointers8[0] + hdr.xsize * bytesperpixel * i; + + for (y = 0; y < ysize; y++) + { + switch (bytesperpixel) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + row_pointers8[y][x] = img->imagedata8[0][y][4 * x]; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + row_pointers8[y][2 * x] = img->imagedata8[0][y][4 * x]; + row_pointers8[y][2 * x + 1] = img->imagedata8[0][y][4 * x + 3]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers8[y][3 * x + 2] = img->imagedata8[0][y][4 * x]; + row_pointers8[y][3 * x + 1] = img->imagedata8[0][y][4 * x + 1]; + row_pointers8[y][3 * x] = img->imagedata8[0][y][4 * x + 2]; + } + break; + case 4: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers8[y][4 * x + 2] = img->imagedata8[0][y][4 * x]; + row_pointers8[y][4 * x + 1] = img->imagedata8[0][y][4 * x + 1]; + row_pointers8[y][4 * x] = img->imagedata8[0][y][4 * x + 2]; + row_pointers8[y][4 * x + 3] = img->imagedata8[0][y][4 * x + 3]; + } + break; + } + } + } + else // if bitness == 16 + { + row_pointers16 = new uint16_t *[hdr.ysize]; + row_pointers16[0] = new uint16_t[hdr.xsize * hdr.ysize * bytesperpixel]; + for (i = 1; i < hdr.ysize; i++) + row_pointers16[i] = row_pointers16[0] + hdr.xsize * bytesperpixel * i; + + for (y = 0; y < ysize; y++) + { + switch (bytesperpixel) + { + case 1: // single-component, treated as Luminance + for (x = 0; x < xsize; x++) + { + row_pointers16[y][x] = img->imagedata16[0][y][4 * x]; + } + break; + case 2: // two-component, treated as Luminance-Alpha + for (x = 0; x < xsize; x++) + { + row_pointers16[y][2 * x] = img->imagedata16[0][y][4 * x]; + row_pointers16[y][2 * x + 1] = img->imagedata16[0][y][4 * x + 3]; + } + break; + case 3: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers16[y][3 * x + 2] = img->imagedata16[0][y][4 * x]; + row_pointers16[y][3 * x + 1] = img->imagedata16[0][y][4 * x + 1]; + row_pointers16[y][3 * x] = img->imagedata16[0][y][4 * x + 2]; + } + break; + case 4: // three-component, treated as RGB + for (x = 0; x < xsize; x++) + { + row_pointers16[y][4 * x + 2] = img->imagedata16[0][y][4 * x]; + row_pointers16[y][4 * x + 1] = img->imagedata16[0][y][4 * x + 1]; + row_pointers16[y][4 * x] = img->imagedata16[0][y][4 * x + 2]; + row_pointers16[y][4 * x + 3] = img->imagedata16[0][y][4 * x + 3]; + } + break; + } + } + } + + + + int retval = image_channels; + + // then try writing it all to file. + FILE *wf = fopen(tga_filename, "wb"); + if (wf) + { + if (bitness == 8) + { + size_t expected_bytes_written = 18 + bytesperpixel * xsize * ysize; + size_t hdr_bytes_written = fwrite(&hdr, 1, 18, wf); + size_t data_bytes_written = fwrite(row_pointers8[0], 1, bytesperpixel * xsize * ysize, wf); + fclose(wf); + if (hdr_bytes_written + data_bytes_written != expected_bytes_written) + retval = -1; + } + else + { + size_t expected_bytes_written = 18 + bytesperpixel * xsize * ysize * sizeof(uint16_t); + size_t hdr_bytes_written = fwrite(&hdr, 1, 18, wf); + size_t data_bytes_written = fwrite(row_pointers16[0], 1, bytesperpixel * xsize * ysize * sizeof(uint16_t), wf); + fclose(wf); + if (hdr_bytes_written + data_bytes_written != expected_bytes_written) + retval = -1; + } + } + else + { + retval = -1; + } + + if (row_pointers8) + { + delete[]row_pointers8[0]; + delete[]row_pointers8; + } + if (row_pointers16) + { + delete[]row_pointers16[0]; + delete[]row_pointers16; + } + + return retval; +} diff --git a/third_party/astcenc/Source/astc_symbolic_physical.cpp b/third_party/astcenc/Source/astc_symbolic_physical.cpp new file mode 100644 index 0000000000..d395b8cfcd --- /dev/null +++ b/third_party/astcenc/Source/astc_symbolic_physical.cpp @@ -0,0 +1,431 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Functions to convert a compressed block between the symbolic and + * the physical representation. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +// routine to write up to 8 bits +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; +} + + +// routine to read up to 8 bits +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; +} + + +int bitrev8(int p) +{ + p = ((p & 0xF) << 4) | ((p >> 4) & 0xF); + p = ((p & 0x33) << 2) | ((p >> 2) & 0x33); + p = ((p & 0x55) << 1) | ((p >> 1) & 0x55); + return p; +} + + + + +physical_compressed_block symbolic_to_physical(int xdim, int ydim, int zdim, const symbolic_compressed_block * sc) +{ + int i, j; + physical_compressed_block res; + + + if (sc->block_mode == -2) + { + // UNORM16 constant-color block. + // This encodes separate constant-color blocks. There is currently + // no attempt to coalesce them into larger void-extents. + + static const uint8_t cbytes[8] = { 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + for (i = 0; i < 8; i++) + res.data[i] = cbytes[i]; + + for (i = 0; i < 4; i++) + { + res.data[2 * i + 8] = sc->constant_color[i] & 0xFF; + res.data[2 * i + 9] = (sc->constant_color[i] >> 8) & 0xFF; + } + return res; + } + + + if (sc->block_mode == -1) + { + // FP16 constant-color block. + // This encodes separate constant-color blocks. There is currently + // no attempt to coalesce them into larger void-extents. + + static const uint8_t cbytes[8] = { 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + for (i = 0; i < 8; i++) + res.data[i] = cbytes[i]; + + for (i = 0; i < 4; i++) + { + res.data[2 * i + 8] = sc->constant_color[i] & 0xFF; + res.data[2 * i + 9] = (sc->constant_color[i] >> 8) & 0xFF; + } + return res; + } + + + + int partition_count = sc->partition_count; + + // first, compress the weights. They are encoded as an ordinary + // integer-sequence, then bit-reversed + uint8_t weightbuf[16]; + for (i = 0; i < 16; i++) + weightbuf[i] = 0; + + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + const decimation_table *const *ixtab2 = bsd->decimation_tables; + + + int weight_count = ixtab2[bsd->block_modes[sc->block_mode].decimation_mode]->num_weights; + int weight_quantization_method = bsd->block_modes[sc->block_mode].quantization_mode; + int is_dual_plane = bsd->block_modes[sc->block_mode].is_dual_plane; + + int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; + + int bits_for_weights = compute_ise_bitcount(real_weight_count, + (quantization_method) weight_quantization_method); + + + if (is_dual_plane) + { + uint8_t weights[64]; + for (i = 0; i < weight_count; i++) + { + weights[2 * i] = sc->plane1_weights[i]; + weights[2 * i + 1] = sc->plane2_weights[i]; + } + encode_ise(weight_quantization_method, real_weight_count, weights, weightbuf, 0); + } + else + { + encode_ise(weight_quantization_method, weight_count, sc->plane1_weights, weightbuf, 0); + } + + for (i = 0; i < 16; i++) + res.data[i] = bitrev8(weightbuf[15 - i]); + + write_bits(sc->block_mode, 11, 0, res.data); + write_bits(partition_count - 1, 2, 11, res.data); + + int below_weights_pos = 128 - bits_for_weights; + + // encode partition index and color endpoint types for blocks with + // 2 or more partitions. + if (partition_count > 1) + { + write_bits(sc->partition_index, 6, 13, res.data); + write_bits(sc->partition_index >> 6, PARTITION_BITS - 6, 19, res.data); + + if (sc->color_formats_matched) + { + write_bits(sc->color_formats[0] << 2, 6, 13 + PARTITION_BITS, res.data); + } + else + { + // go through the selected endpoint type classes for each partition + // in order to determine the lowest class present. + int low_class = 4; + for (i = 0; i < partition_count; i++) + { + int class_of_format = sc->color_formats[i] >> 2; + if (class_of_format < low_class) + low_class = class_of_format; + } + if (low_class == 3) + low_class = 2; + int encoded_type = low_class + 1; + int bitpos = 2; + for (i = 0; i < partition_count; i++) + { + int classbit_of_format = (sc->color_formats[i] >> 2) - low_class; + + encoded_type |= classbit_of_format << bitpos; + bitpos++; + } + for (i = 0; i < partition_count; i++) + { + int lowbits_of_format = sc->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_BITS, res.data); + write_bits(encoded_type_highpart, encoded_type_highpart_size, encoded_type_highpart_pos, res.data); + + below_weights_pos -= encoded_type_highpart_size; + } + } + + else + write_bits(sc->color_formats[0], 4, 13, res.data); + + // in dual-plane mode, encode the color component of the second plane of weights + if (is_dual_plane) + write_bits(sc->plane2_color_component, 2, below_weights_pos - 2, res.data); + + // finally, encode the color bits + // first, get hold of all the color components to encode + uint8_t values_to_encode[32]; + int valuecount_to_encode = 0; + for (i = 0; i < sc->partition_count; i++) + { + int vals = 2 * (sc->color_formats[i] >> 2) + 2; + for (j = 0; j < vals; j++) + values_to_encode[j + valuecount_to_encode] = sc->color_values[i][j]; + valuecount_to_encode += vals; + } + // then, encode an ISE based on them. + encode_ise(sc->color_quantization_level, valuecount_to_encode, values_to_encode, res.data, (sc->partition_count == 1 ? 17 : 19 + PARTITION_BITS)); + + return res; +} + + +void physical_to_symbolic(int xdim, int ydim, int zdim, physical_compressed_block pb, symbolic_compressed_block * res) +{ + uint8_t bswapped[16]; + int i, j; + + res->error_block = 0; + + // get hold of the block-size descriptor and the decimation tables. + const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim); + const decimation_table *const *ixtab2 = bsd->decimation_tables; + + // extract header fields + int block_mode = read_bits(11, 0, pb.data); + + + if ((block_mode & 0x1FF) == 0x1FC) + { + // void-extent block! + + // check what format the data has + if (block_mode & 0x200) + res->block_mode = -1; // floating-point + else + res->block_mode = -2; // unorm16. + + res->partition_count = 0; + for (i = 0; i < 4; i++) + { + res->constant_color[i] = pb.data[2 * i + 8] | (pb.data[2 * i + 9] << 8); + } + + // additionally, check that the void-extent + if (zdim == 1) + { + // 2D void-extent + int rsvbits = read_bits(2, 10, pb.data); + if (rsvbits != 3) + res->error_block = 1; + + int vx_low_s = read_bits(8, 12, pb.data) | (read_bits(5, 12 + 8, pb.data) << 8); + int vx_high_s = read_bits(8, 25, pb.data) | (read_bits(5, 25 + 8, pb.data) << 8); + int vx_low_t = read_bits(8, 38, pb.data) | (read_bits(5, 38 + 8, pb.data) << 8); + int vx_high_t = read_bits(8, 51, pb.data) | (read_bits(5, 51 + 8, pb.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) + res->error_block = 1; + } + else + { + // 3D void-extent + int vx_low_s = read_bits(9, 10, pb.data); + int vx_high_s = read_bits(9, 19, pb.data); + int vx_low_t = read_bits(9, 28, pb.data); + int vx_high_t = read_bits(9, 37, pb.data); + int vx_low_p = read_bits(9, 46, pb.data); + int vx_high_p = read_bits(9, 55, pb.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) + res->error_block = 1; + } + + return; + } + + if (bsd->block_modes[block_mode].permit_decode == 0) + { + res->error_block = 1; + return; + } + + int weight_count = ixtab2[bsd->block_modes[block_mode].decimation_mode]->num_weights; + int weight_quantization_method = bsd->block_modes[block_mode].quantization_mode; + int is_dual_plane = bsd->block_modes[block_mode].is_dual_plane; + + int real_weight_count = is_dual_plane ? 2 * weight_count : weight_count; + + int partition_count = read_bits(2, 11, pb.data) + 1; + + res->block_mode = block_mode; + res->partition_count = partition_count; + + for (i = 0; i < 16; i++) + bswapped[i] = bitrev8(pb.data[15 - i]); + + int bits_for_weights = compute_ise_bitcount(real_weight_count, + (quantization_method) weight_quantization_method); + + int below_weights_pos = 128 - bits_for_weights; + + if (is_dual_plane) + { + uint8_t indices[64]; + decode_ise(weight_quantization_method, real_weight_count, bswapped, indices, 0); + for (i = 0; i < weight_count; i++) + { + res->plane1_weights[i] = indices[2 * i]; + res->plane2_weights[i] = indices[2 * i + 1]; + } + } + else + { + decode_ise(weight_quantization_method, weight_count, bswapped, res->plane1_weights, 0); + } + + if (is_dual_plane && partition_count == 4) + res->error_block = 1; + + + + res->color_formats_matched = 0; + + // then, determine the format of each endpoint pair + int color_formats[4]; + int encoded_type_highpart_size = 0; + if (partition_count == 1) + { + color_formats[0] = read_bits(4, 13, pb.data); + res->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_BITS, pb.data) | (read_bits(encoded_type_highpart_size, below_weights_pos, pb.data) << 6); + int baseclass = encoded_type & 0x3; + if (baseclass == 0) + { + for (i = 0; i < partition_count; i++) + { + color_formats[i] = (encoded_type >> 2) & 0xF; + } + below_weights_pos += encoded_type_highpart_size; + res->color_formats_matched = 1; + encoded_type_highpart_size = 0; + } + else + { + int bitpos = 2; + baseclass--; + for (i = 0; i < partition_count; i++) + { + color_formats[i] = (((encoded_type >> bitpos) & 1) + baseclass) << 2; + bitpos++; + } + for (i = 0; i < partition_count; i++) + { + color_formats[i] |= (encoded_type >> bitpos) & 3; + bitpos += 2; + } + } + res->partition_index = read_bits(6, 13, pb.data) | (read_bits(PARTITION_BITS - 6, 19, pb.data) << 6); + + } + for (i = 0; i < partition_count; i++) + res->color_formats[i] = color_formats[i]; + + + // then, determine the number of integers we need to unpack for the endpoint pairs + int color_integer_count = 0; + for (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) + res->error_block = 1; + + // then, determine the color endpoint format to use for these integers + static const int color_bits_arr[5] = { -1, 115 - 4, 113 - 4 - PARTITION_BITS, 113 - 4 - PARTITION_BITS, 113 - 4 - PARTITION_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_quantization_level = quantization_mode_table[color_integer_count >> 1][color_bits]; + res->color_quantization_level = color_quantization_level; + if (color_quantization_level < 4) + res->error_block = 1; + + + // then unpack the integer-bits + uint8_t values_to_decode[32]; + decode_ise(color_quantization_level, color_integer_count, pb.data, values_to_decode, (partition_count == 1 ? 17 : 19 + PARTITION_BITS)); + + // and distribute them over the endpoint types + int valuecount_to_decode = 0; + + for (i = 0; i < partition_count; i++) + { + int vals = 2 * (color_formats[i] >> 2) + 2; + for (j = 0; j < vals; j++) + res->color_values[i][j] = values_to_decode[j + valuecount_to_decode]; + valuecount_to_decode += vals; + } + + // get hold of color component for second-plane in the case of dual plane of weights. + if (is_dual_plane) + res->plane2_color_component = read_bits(2, below_weights_pos - 2, pb.data); + +} diff --git a/third_party/astcenc/Source/astc_toplevel.cpp b/third_party/astcenc/Source/astc_toplevel.cpp new file mode 100644 index 0000000000..8c6ffad97d --- /dev/null +++ b/third_party/astcenc/Source/astc_toplevel.cpp @@ -0,0 +1,2538 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2013 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Top level functions - parsing command line, managing conversions, + * etc. + * + * This is also where main() lives. + */ +/*----------------------------------------------------------------------------*/ + +#include "astc_codec_internals.h" + +#include +#include +#include + +#ifndef WIN32 + #include + #include + #include + + double get_time() + { + timeval tv; + gettimeofday(&tv, 0); + + return (double)tv.tv_sec + (double)tv.tv_usec * 1.0e-6; + } + + + int astc_codec_unlink(const char *filename) + { + return unlink(filename); + } + +#else + // Windows.h defines IGNORE, so we must #undef our own version. + #undef IGNORE + + // Define pthread-like functions in terms of Windows threading API + #define WIN32_LEAN_AND_MEAN + #include + + typedef HANDLE pthread_t; + typedef int pthread_attr_t; + + int pthread_create(pthread_t * thread, const pthread_attr_t * attribs, void *(*threadfunc) (void *), void *thread_arg) + { + *thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadfunc, thread_arg, 0, NULL); + return 0; + } + + int pthread_join(pthread_t thread, void **value) + { + WaitForSingleObject(thread, INFINITE); + return 0; + } + + double get_time() + { + FILETIME tv; + GetSystemTimeAsFileTime(&tv); + + unsigned __int64 ticks = tv.dwHighDateTime; + ticks = (ticks << 32) | tv.dwLowDateTime; + + return ((double)ticks) / 1.0e7; + } + + // Define an unlink() function in terms of the Win32 DeleteFile function. + int astc_codec_unlink(const char *filename) + { + BOOL res = DeleteFileA(filename); + return (res ? 0 : -1); + } +#endif + +#ifdef DEBUG_CAPTURE_NAN + #ifndef _GNU_SOURCE + #define _GNU_SOURCE + #endif + + #include +#endif + +// Define this to be 1 to allow "illegal" block sizes +#define DEBUG_ALLOW_ILLEGAL_BLOCK_SIZES 0 + +extern int block_mode_histogram[2048]; + +#ifdef DEBUG_PRINT_DIAGNOSTICS + int print_diagnostics = 0; + int diagnostics_tile = -1; +#endif + +int print_tile_errors = 0; + +int print_statistics = 0; + +int progress_counter_divider = 1; + +int rgb_force_use_of_hdr = 0; +int alpha_force_use_of_hdr = 0; + + +static double start_time; +static double end_time; +static double start_coding_time; +static double end_coding_time; + + +// code to discover the number of logical CPUs available. + +#if defined(__APPLE__) + #define _DARWIN_C_SOURCE + #include + #include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) + #include +#else + #include +#endif + + + +unsigned get_number_of_cpus(void) +{ + unsigned n_cpus = 1; + + #ifdef __linux__ + cpu_set_t mask; + CPU_ZERO(&mask); + sched_getaffinity(getpid(), sizeof(mask), &mask); + n_cpus = 0; + for (unsigned i = 0; i < CPU_SETSIZE; ++i) + { + if (CPU_ISSET(i, &mask)) + n_cpus++; + } + if (n_cpus == 0) + n_cpus = 1; + + #elif defined (_WIN32) || defined(__CYGWIN__) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + n_cpus = sysinfo.dwNumberOfProcessors; + + #elif defined(__APPLE__) + int mib[4]; + size_t length = 100; + mib[0] = CTL_HW; + mib[1] = HW_AVAILCPU; + sysctl(mib, 2, &n_cpus, &length, NULL, 0); + #endif + + return n_cpus; +} + +void astc_codec_internal_error(const char *filename, int linenum) +{ + printf("Internal error: File=%s Line=%d\n", filename, linenum); + exit(1); +} + +#define MAGIC_FILE_CONSTANT 0x5CA1AB13 + +struct astc_header +{ + uint8_t magic[4]; + uint8_t blockdim_x; + uint8_t blockdim_y; + uint8_t blockdim_z; + uint8_t xsize[3]; // x-size = xsize[0] + xsize[1] + xsize[2] + uint8_t ysize[3]; // x-size, y-size and z-size are given in texels; + uint8_t zsize[3]; // block count is inferred +}; + + +int suppress_progress_counter = 0; +int perform_srgb_transform = 0; + +astc_codec_image *load_astc_file(const char *filename, int bitness, astc_decode_mode decode_mode, swizzlepattern swz_decode) +{ + int x, y, z; + FILE *f = fopen(filename, "rb"); + if (!f) + { + printf("Failed to open file %s\n", filename); + exit(1); + } + astc_header hdr; + size_t hdr_bytes_read = fread(&hdr, 1, sizeof(astc_header), f); + if (hdr_bytes_read != sizeof(astc_header)) + { + fclose(f); + printf("Failed to read file %s\n", filename); + exit(1); + } + + uint32_t magicval = hdr.magic[0] + 256 * (uint32_t) (hdr.magic[1]) + 65536 * (uint32_t) (hdr.magic[2]) + 16777216 * (uint32_t) (hdr.magic[3]); + + if (magicval != MAGIC_FILE_CONSTANT) + { + fclose(f); + printf("File %s not recognized\n", filename); + exit(1); + } + + int xdim = hdr.blockdim_x; + int ydim = hdr.blockdim_y; + int zdim = hdr.blockdim_z; + + if ( (xdim < 3 || xdim > 6 || ydim < 3 || ydim > 6 || zdim < 3 || zdim > 6) && + (xdim < 4 || xdim == 7 || xdim == 9 || xdim == 11 || xdim > 12 || + ydim < 4 || ydim == 7 || ydim == 9 || ydim == 11 || ydim > 12 || zdim != 1) ) + { + fclose(f); + printf("File %s not recognized %d %d %d\n", filename, xdim, ydim, zdim); + exit(1); + } + + + int xsize = hdr.xsize[0] + 256 * hdr.xsize[1] + 65536 * hdr.xsize[2]; + int ysize = hdr.ysize[0] + 256 * hdr.ysize[1] + 65536 * hdr.ysize[2]; + int zsize = hdr.zsize[0] + 256 * hdr.zsize[1] + 65536 * hdr.zsize[2]; + + if (xsize == 0 || ysize == 0 || zsize == 0) + { + fclose(f); + printf("File %s has zero dimension %d %d %d\n", filename, xsize, ysize, zsize); + exit(1); + } + + + int xblocks = (xsize + xdim - 1) / xdim; + int yblocks = (ysize + ydim - 1) / ydim; + int zblocks = (zsize + zdim - 1) / zdim; + + uint8_t *buffer = (uint8_t *) malloc(xblocks * yblocks * zblocks * 16); + if (!buffer) + { + fclose(f); + printf("Ran out of memory\n"); + exit(1); + } + size_t bytes_to_read = xblocks * yblocks * zblocks * 16; + size_t bytes_read = fread(buffer, 1, bytes_to_read, f); + fclose(f); + if (bytes_read != bytes_to_read) + { + printf("Failed to read file %s\n", filename); + exit(1); + } + + + astc_codec_image *img = allocate_image(bitness, xsize, ysize, zsize, 0); + initialize_image(img); + + imageblock pb; + for (z = 0; z < zblocks; z++) + for (y = 0; y < yblocks; y++) + for (x = 0; x < xblocks; x++) + { + int offset = (((z * yblocks + y) * xblocks) + x) * 16; + uint8_t *bp = buffer + offset; + physical_compressed_block pcb = *(physical_compressed_block *) bp; + symbolic_compressed_block scb; + physical_to_symbolic(xdim, ydim, zdim, pcb, &scb); + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, &scb, &pb); + write_imageblock(img, &pb, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, swz_decode); + } + + free(buffer); + + return img; +} + + + +struct encode_astc_image_info +{ + int xdim; + int ydim; + int zdim; + const error_weighting_params *ewp; + uint8_t *buffer; + int *counters; + int pack_and_unpack; + int thread_id; + int threadcount; + astc_decode_mode decode_mode; + swizzlepattern swz_encode; + swizzlepattern swz_decode; + int *threads_completed; + const astc_codec_image *input_image; + astc_codec_image *output_image; +}; + + + +void *encode_astc_image_threadfunc(void *vblk) +{ + const encode_astc_image_info *blk = (const encode_astc_image_info *)vblk; + int xdim = blk->xdim; + int ydim = blk->ydim; + int zdim = blk->zdim; + uint8_t *buffer = blk->buffer; + const error_weighting_params *ewp = blk->ewp; + int thread_id = blk->thread_id; + int threadcount = blk->threadcount; + int *counters = blk->counters; + int pack_and_unpack = blk->pack_and_unpack; + astc_decode_mode decode_mode = blk->decode_mode; + swizzlepattern swz_encode = blk->swz_encode; + swizzlepattern swz_decode = blk->swz_decode; + int *threads_completed = blk->threads_completed; + const astc_codec_image *input_image = blk->input_image; + astc_codec_image *output_image = blk->output_image; + + imageblock pb; + int ctr = thread_id; + int pctr = 0; + + int x, y, z, i; + int xsize = input_image->xsize; + int ysize = input_image->ysize; + int zsize = input_image->zsize; + int xblocks = (xsize + xdim - 1) / xdim; + int yblocks = (ysize + ydim - 1) / ydim; + int zblocks = (zsize + zdim - 1) / zdim; + + int owns_progress_counter = 0; + + //allocate memory for temporary buffers + compress_symbolic_block_buffers temp_buffers; + temp_buffers.ewb = new error_weight_block; + temp_buffers.ewbo = new error_weight_block_orig; + temp_buffers.tempblocks = new symbolic_compressed_block[4]; + temp_buffers.temp = new imageblock; + temp_buffers.planes2 = new compress_fixed_partition_buffers; + temp_buffers.planes2->ei1 = new endpoints_and_weights; + temp_buffers.planes2->ei2 = new endpoints_and_weights; + temp_buffers.planes2->eix1 = new endpoints_and_weights[MAX_DECIMATION_MODES]; + temp_buffers.planes2->eix2 = new endpoints_and_weights[MAX_DECIMATION_MODES]; + temp_buffers.planes2->decimated_quantized_weights = new float[2 * MAX_DECIMATION_MODES * MAX_WEIGHTS_PER_BLOCK]; + temp_buffers.planes2->decimated_weights = new float[2 * MAX_DECIMATION_MODES * MAX_WEIGHTS_PER_BLOCK]; + temp_buffers.planes2->flt_quantized_decimated_quantized_weights = new float[2 * MAX_WEIGHT_MODES * MAX_WEIGHTS_PER_BLOCK]; + temp_buffers.planes2->u8_quantized_decimated_quantized_weights = new uint8_t[2 * MAX_WEIGHT_MODES * MAX_WEIGHTS_PER_BLOCK]; + temp_buffers.plane1 = temp_buffers.planes2; + + for (z = 0; z < zblocks; z++) + for (y = 0; y < yblocks; y++) + for (x = 0; x < xblocks; x++) + { + if (ctr == 0) + { + int offset = ((z * yblocks + y) * xblocks + x) * 16; + uint8_t *bp = buffer + offset; + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (diagnostics_tile < 0 || diagnostics_tile == pctr) + { + print_diagnostics = (diagnostics_tile == pctr) ? 1 : 0; + #endif + fetch_imageblock(input_image, &pb, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, swz_encode); + symbolic_compressed_block scb; + compress_symbolic_block(input_image, decode_mode, xdim, ydim, zdim, ewp, &pb, &scb, &temp_buffers); + if (pack_and_unpack) + { + decompress_symbolic_block(decode_mode, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, &scb, &pb); + write_imageblock(output_image, &pb, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, swz_decode); + } + else + { + physical_compressed_block pcb; + pcb = symbolic_to_physical(xdim, ydim, zdim, &scb); + *(physical_compressed_block *) bp = pcb; + } + #ifdef DEBUG_PRINT_DIAGNOSTICS + } + #endif + + counters[thread_id]++; + ctr = threadcount - 1; + + pctr++; + + // routine to print the progress counter. + if (suppress_progress_counter == 0 && (pctr % progress_counter_divider) == 0 && print_tile_errors == 0 && print_statistics == 0) + { + int do_print = 1; + // the current thread has the responsibility for printing the progress counter + // if every previous thread has completed. Also, if we have ever received the + // responsibility to print the progress counter, we are going to keep it + // until the thread is completed. + if (!owns_progress_counter) + { + for (i = thread_id - 1; i >= 0; i--) + { + if (threads_completed[i] == 0) + { + do_print = 0; + break; + } + } + } + if (do_print) + { + owns_progress_counter = 1; + int summa = 0; + for (i = 0; i < threadcount; i++) + summa += counters[i]; + printf("\r%d", summa); + fflush(stdout); + } + } + } + else + ctr--; + } + + delete[] temp_buffers.planes2->decimated_quantized_weights; + delete[] temp_buffers.planes2->decimated_weights; + delete[] temp_buffers.planes2->flt_quantized_decimated_quantized_weights; + delete[] temp_buffers.planes2->u8_quantized_decimated_quantized_weights; + delete[] temp_buffers.planes2->eix1; + delete[] temp_buffers.planes2->eix2; + delete temp_buffers.planes2->ei1; + delete temp_buffers.planes2->ei2; + delete temp_buffers.planes2; + delete[] temp_buffers.tempblocks; + delete temp_buffers.temp; + delete temp_buffers.ewbo; + delete temp_buffers.ewb; + + threads_completed[thread_id] = 1; + return NULL; +} + + +void encode_astc_image(const astc_codec_image * input_image, + astc_codec_image * output_image, + int xdim, + int ydim, + int zdim, + const error_weighting_params * ewp, astc_decode_mode decode_mode, swizzlepattern swz_encode, swizzlepattern swz_decode, uint8_t * buffer, int pack_and_unpack, int threadcount) +{ + int i; + int *counters = new int[threadcount]; + int *threads_completed = new int[threadcount]; + + // before entering into the multi-threaded routine, ensure that the block size descriptors + // and the partition table descriptors needed actually exist. + get_block_size_descriptor(xdim, ydim, zdim); + get_partition_table(xdim, ydim, zdim, 0); + + encode_astc_image_info *ai = new encode_astc_image_info[threadcount]; + for (i = 0; i < threadcount; i++) + { + ai[i].xdim = xdim; + ai[i].ydim = ydim; + ai[i].zdim = zdim; + ai[i].buffer = buffer; + ai[i].ewp = ewp; + ai[i].counters = counters; + ai[i].pack_and_unpack = pack_and_unpack; + ai[i].thread_id = i; + ai[i].threadcount = threadcount; + ai[i].decode_mode = decode_mode; + ai[i].swz_encode = swz_encode; + ai[i].swz_decode = swz_decode; + ai[i].threads_completed = threads_completed; + ai[i].input_image = input_image; + ai[i].output_image = output_image; + counters[i] = 0; + threads_completed[i] = 0; + } + + if (threadcount == 1) + encode_astc_image_threadfunc(&ai[0]); + else + { + pthread_t *threads = new pthread_t[threadcount]; + for (i = 0; i < threadcount; i++) + pthread_create(&(threads[i]), NULL, encode_astc_image_threadfunc, (void *)(&(ai[i]))); + + for (i = 0; i < threadcount; i++) + pthread_join(threads[i], NULL); + delete[]threads; + } + + delete[]ai; + delete[]counters; + delete[]threads_completed; +} + + +void store_astc_file(const astc_codec_image * input_image, + const char *filename, int xdim, int ydim, int zdim, const error_weighting_params * ewp, astc_decode_mode decode_mode, swizzlepattern swz_encode, int threadcount) +{ + int xsize = input_image->xsize; + int ysize = input_image->ysize; + int zsize = input_image->zsize; + + int xblocks = (xsize + xdim - 1) / xdim; + int yblocks = (ysize + ydim - 1) / ydim; + int zblocks = (zsize + zdim - 1) / zdim; + + uint8_t *buffer = (uint8_t *) malloc(xblocks * yblocks * zblocks * 16); + if (!buffer) + { + printf("Ran out of memory\n"); + exit(1); + } + + if (!suppress_progress_counter) + printf("%d blocks to process ..\n", xblocks * yblocks * zblocks); + + encode_astc_image(input_image, NULL, xdim, ydim, zdim, ewp, decode_mode, swz_encode, swz_encode, buffer, 0, threadcount); + + end_coding_time = get_time(); + + astc_header hdr; + hdr.magic[0] = MAGIC_FILE_CONSTANT & 0xFF; + hdr.magic[1] = (MAGIC_FILE_CONSTANT >> 8) & 0xFF; + hdr.magic[2] = (MAGIC_FILE_CONSTANT >> 16) & 0xFF; + hdr.magic[3] = (MAGIC_FILE_CONSTANT >> 24) & 0xFF; + hdr.blockdim_x = xdim; + hdr.blockdim_y = ydim; + hdr.blockdim_z = zdim; + hdr.xsize[0] = xsize & 0xFF; + hdr.xsize[1] = (xsize >> 8) & 0xFF; + hdr.xsize[2] = (xsize >> 16) & 0xFF; + hdr.ysize[0] = ysize & 0xFF; + hdr.ysize[1] = (ysize >> 8) & 0xFF; + hdr.ysize[2] = (ysize >> 16) & 0xFF; + hdr.zsize[0] = zsize & 0xFF; + hdr.zsize[1] = (zsize >> 8) & 0xFF; + hdr.zsize[2] = (zsize >> 16) & 0xFF; + + FILE *wf = fopen(filename, "wb"); + fwrite(&hdr, 1, sizeof(astc_header), wf); + fwrite(buffer, 1, xblocks * yblocks * zblocks * 16, wf); + fclose(wf); + free(buffer); +} + + + +astc_codec_image *pack_and_unpack_astc_image(const astc_codec_image * input_image, + int xdim, + int ydim, + int zdim, + const error_weighting_params * ewp, astc_decode_mode decode_mode, swizzlepattern swz_encode, swizzlepattern swz_decode, int bitness, int threadcount) +{ + int xsize = input_image->xsize; + int ysize = input_image->ysize; + int zsize = input_image->zsize; + + astc_codec_image *img = allocate_image(bitness, xsize, ysize, zsize, 0); + + /* + allocate_output_image_space( bitness, xsize, ysize, zsize ); */ + + int xblocks = (xsize + xdim - 1) / xdim; + int yblocks = (ysize + ydim - 1) / ydim; + int zblocks = (zsize + zdim - 1) / zdim; + + if (!suppress_progress_counter) + printf("%d blocks to process...\n", xblocks * yblocks * zblocks); + + encode_astc_image(input_image, img, xdim, ydim, zdim, ewp, decode_mode, swz_encode, swz_decode, NULL, 1, threadcount); + + if (!suppress_progress_counter) + printf("\n"); + + return img; +} + + +void find_closest_blockdim_2d(float target_bitrate, int *x, int *y, int consider_illegal) +{ + int blockdims[6] = { 4, 5, 6, 8, 10, 12 }; + + float best_error = 1000; + float aspect_of_best = 1; + int i, j; + + // Y dimension + for (i = 0; i < 6; i++) + { + // X dimension + for (j = i; j < 6; j++) + { + // NxN MxN 8x5 10x5 10x6 + int is_legal = (j==i) || (j==i+1) || (j==3 && i==1) || (j==4 && i==1) || (j==4 && i==2); + + if(consider_illegal || is_legal) + { + float bitrate = 128.0f / (blockdims[i] * blockdims[j]); + float bitrate_error = fabs(bitrate - target_bitrate); + float aspect = (float)blockdims[j] / blockdims[i]; + if (bitrate_error < best_error || (bitrate_error == best_error && aspect < aspect_of_best)) + { + *x = blockdims[j]; + *y = blockdims[i]; + best_error = bitrate_error; + aspect_of_best = aspect; + } + } + } + } +} + + + +void find_closest_blockdim_3d(float target_bitrate, int *x, int *y, int *z, int consider_illegal) +{ + int blockdims[4] = { 3, 4, 5, 6 }; + + float best_error = 1000; + float aspect_of_best = 1; + int i, j, k; + + for (i = 0; i < 4; i++) // Z + for (j = i; j < 4; j++) // Y + for (k = j; k < 4; k++) // X + { + // NxNxN MxNxN MxMxN + int is_legal = ((k==j)&&(j==i)) || ((k==j+1)&&(j==i)) || ((k==j)&&(j==i+1)); + + if(consider_illegal || is_legal) + { + float bitrate = 128.0f / (blockdims[i] * blockdims[j] * blockdims[k]); + float bitrate_error = fabs(bitrate - target_bitrate); + float aspect = (float)blockdims[k] / blockdims[j] + (float)blockdims[j] / blockdims[i] + (float)blockdims[k] / blockdims[i]; + + if (bitrate_error < best_error || (bitrate_error == best_error && aspect < aspect_of_best)) + { + *x = blockdims[k]; + *y = blockdims[j]; + *z = blockdims[i]; + best_error = bitrate_error; + aspect_of_best = aspect; + } + } + } +} + + +void compare_two_files(const char *filename1, const char *filename2, int low_fstop, int high_fstop, int psnrmode) +{ + int load_result1; + int load_result2; + astc_codec_image *img1 = astc_codec_load_image(filename1, 0, &load_result1); + if (load_result1 < 0) + { + printf("Failed to load file %s.\n", filename1); + exit(1); + } + astc_codec_image *img2 = astc_codec_load_image(filename2, 0, &load_result2); + if (load_result2 < 0) + { + printf("Failed to load file %s.\n", filename2); + exit(1); + } + + int file1_components = load_result1 & 0x7; + int file2_components = load_result2 & 0x7; + int comparison_components = MAX(file1_components, file2_components); + + int compare_hdr = 0; + if (load_result1 & 0x80) + compare_hdr = 1; + if (load_result2 & 0x80) + compare_hdr = 1; + + compute_error_metrics(compare_hdr, comparison_components, img1, img2, low_fstop, high_fstop, psnrmode); +} + + +union if32 +{ + float f; + int32_t s; + uint32_t u; +}; + + +// The ASTC codec is written with the assumption that a float threaded through +// the "if32" union will in fact be stored and reloaded as a 32-bit IEEE-754 single-precision +// float, stored with round-to-nearest rounding. This is always the case in an +// IEEE-754 compliant system, however not every system is actually IEEE-754 compliant +// in the first place. As such, we run a quick test to check that this is actually the case +// (e.g. gcc on 32-bit x86 will typically fail unless -msse2 -mfpmath=sse2 is specified). + +volatile float xprec_testval = 2.51f; +void test_inappropriate_extended_precision(void) +{ + if32 p; + p.f = xprec_testval + 12582912.0f; + float q = p.f - 12582912.0f; + if (q != 3.0f) + { + printf("Single-precision test failed; please recompile with proper IEEE-754 support.\n"); + exit(1); + } +} + +// Debug routine to dump the entire image if requested. +void dump_image(astc_codec_image * img) +{ + int x, y, z, xdim, ydim, zdim; + + printf("\n\nDumping image ( %d x %d x %d + %d)...\n\n", img->xsize, img->ysize, img->zsize, img->padding); + + if (img->zsize != 1) + zdim = img->zsize + 2 * img->padding; + else + zdim = img->zsize; + + ydim = img->ysize + 2 * img->padding; + xdim = img->xsize + 2 * img->padding; + + for (z = 0; z < zdim; z++) + { + if (z != 0) + printf("\n\n"); + for (y = 0; y < ydim; y++) + { + if (y != 0) + printf("\n"); + for (x = 0; x < xdim; x++) + { + printf(" 0x%08X", *(int unsigned *)&img->imagedata8[z][y][x]); + } + } + } + printf("\n\n"); +} + + +int standalone_main(int argc, char **argv) +{ + int i; + + test_inappropriate_extended_precision(); + // initialization routines + prepare_angular_tables(); + build_quantization_mode_table(); + + start_time = get_time(); + + #ifdef DEBUG_CAPTURE_NAN + feenableexcept(FE_DIVBYZERO | FE_INVALID); + #endif + + if (argc < 4) + { + + printf( "ASTC codec version 1.3\n" + "Copyright (C) 2011-2013 ARM Limited\n" + "All rights reserved. Use of this software is subject to terms of its license.\n\n" + "Usage:\n" + "Compress to texture file:\n" + " %s -c [options]\n" + "Decompress from texture file:\n" + " %s -d [options]\n" + "Compress, then immediately decompress to image:\n" + " %s -t [options]\n" + "Compare two files (no compression or decompression):\n" + " %s -compare [options]\n" + "\n" + "When encoding/decoding a texture for use with the LDR-SRGB submode,\n" + "use -cs, -ds, -ts instead of -c, -d, -t.\n" + "When encoding/decoding a texture for use with the LDR-linear submode,\n" + "use -cl, -dl, -tl instead of -c, -d, -t.\n" + "\n" + "For compression, the input file formats supported are\n" + " * PNG (*.png)\n" + " * Targa (*.tga)\n" + " * JPEG (*.jpg)\n" + " * GIF (*.gif) (non-animated only)\n" + " * BMP (*.bmp)\n" + " * Radiance HDR (*.hdr)\n" + " * Khronos Texture KTX (*.ktx)\n" + " * DirectDraw Surface DDS (*.dds)\n" + " * Half-Float-TGA (*.htga)\n" + " * OpenEXR (*.exr; only if 'exr_to_htga' is present in the path)\n" + "\n" + "For the KTX and DDS formats, the following subset of the format\n" + "features are supported; the subset is:\n" + " * 2D and 3D textures supported\n" + " * Uncompressed only, with unorm8, unorm16, float16 or float32 components\n" + " * R, RG, RGB, BGR, RGBA, BGRA, Luminance and Luminance-Alpha texel formats\n" + " * In case of multiple image in one file (mipmap, cube-faces, texture-arrays)\n" + " the codec will read the first one and ignore the other ones.\n" + "\n" + "When using HDR or 3D textures, it is recommended to use the KTX or DDS formats.\n" + "Separate 2D image slices can be assembled into a 3D image using the -array option.\n" + "\n" + "The output file will be an ASTC compressed texture file (recommended filename\n" + "ending .astc)\n" + "\n" + "For decompression, the input file must be an ASTC compressed texture file;\n" + "the following formats are supported for output:\n" + " * Targa (*.tga)\n" + " * KTX (*.ktx)\n" + " * DDS (*.dds)\n" + " * Half-Float-TGA (*.htga)\n" + " * OpenEXR (*.exr; only if t'exr_to_htga' is present in the path)\n" + "\n" + "Targa is suitable only for 2D LDR images; for HDR and/or 3D images,\n" + "please use KTX or DDS.\n" + "\n" + "For compression, the argument specifies the bitrate or block\n" + "dimension to use. This argument can be specified in one of two ways:\n" + " * A decimal number (at least one actual decimal needed). This will cause \n" + " the codec to interpret the number as a desired bitrate, and pick a block\n" + " size to match that bitrate as closely as possible. For example, if you want a\n" + " bitrate of 2.0 bits per texel, then specifiy the argument as 2.0\n" + " * A block size. This specifies the block dimensions to use along the\n" + " X, Y (and for 3D textures) Z axes. The dimensions are separated with\n" + " the character x, with no spaces. For 2D textures, the supported\n" + " dimensions along each axis are picked from the set {4,5,6,8,10,12};\n" + " for 3D textures, the supported dimensions are picked from the\n" + " set {3,4,5,6}. For example, if you wish to encode a 2D texture using the\n" + " 10x6 block size (10 texels per block along the X axis, 6 texels per block\n" + " along the Y axis, then specify the argument as 10x6 .\n" + "Some examples of supported 2D block sizes are:\n" + " 4x4 -> 8.0 bpp\n" + " 5x5 -> 5.12 bpp\n" + " 6x6 -> 3.56 bpp\n" + " 8x6 -> 2.67 bpp\n" + " 8x8 -> 2.0 bpp\n" + " 10x8 -> 1.6 bpp\n" + " 10x10 -> 1.28 bpp\n" + " 10x12 -> 1.07 bpp\n" + " 12x12 -> 0.89 bpp\n" + "If you try to specify a bitrate that can potentially map to multiple different\n" + "block sizes, the codec will choose the block size with the least lopsided\n" + "aspect ratio (e.g. if you specify 2.67, then the codec will choose the\n" + "8x6 block size, not 12x4)\n" + "\n" + "Below is a description of all the available options. Most of them make sense\n" + "for encoding only, however there are some that affect decoding as well\n" + "(such as -dsw and the normal-presets)\n" + "\n" + "\n" + "Built-in error-weighting Presets:\n" + "---------------------------------\n" + "The presets provide easy-to-use combinations of encoding options that\n" + "are designed for use with certain commonly-occurring kinds of\n" + "textures.\n" + "\n" + " -normal_psnr\n" + " For encoding, assume that the input texture is a normal map with the\n" + " X and Y components of the actual normals in the Red and Green\n" + " color channels. The codec will then move the 2nd component to Alpha,\n" + " and apply an error-weighting function based on angular error.\n" + "\n" + " It is possible to use this preset with texture decoding as well,\n" + " in which case it will expand the normal map from 2 to 3 components\n" + " after the actual decoding.\n" + "\n" + " The -normal_psnr preset as a whole is equivalent to the options\n" + " \"-rn -esw rrrg -dsw raz1 -ch 1 0 0 1 -oplimit 1000 -mincorrel 0.99\" .\n" + "\n" + " -normal_percep\n" + " Similar to -normal_psnr, except that it tries to optimize the normal\n" + " map for best possible perceptual results instead of just maximizing\n" + " angular PSNR.\n" + " The -normal_percep preset as a whole is equivalent to the options\n" + " \"-normal_psnr -b 2.5 -v 3 1 1 0 50 0 -va 1 1 0 50 -dblimit 60\" .\n" + "\n" + " -mask\n" + " Assume that the input texture is a texture that contains\n" + " unrelated content in its various color channels, and where\n" + " it is undesirable for errors in one channel to affect\n" + " the other channels.\n" + " Equivalent to \"-v 3 1 1 0 25 0.03 -va 0 25\" .\n" + "\n" + " -alphablend\n" + " Assume that the input texture is an RGB-alpha texture where\n" + " the alpha component is used to represent opacity.\n" + " (0=fully transparent, 1=fully opaque)\n" + " Equivalent to \"-a 1\" .\n" + "\n" + " -hdr\n" + " Assume that the input texture is an HDR texture. If an alpha channel is\n" + " present, it is treated as an LDR channel (e.g. opacity)\n" + " Optimize for 4th-root error for the color and linear error for the alpha.\n" + " Equivalent to\n" + " \"-forcehdr_rgb -v 0 0.75 0 1 0 0 -va 0.02 1 0 0 -dblimit 999\"\n" + "\n" + " -hdra\n" + " Assume that the input texture is an HDR texture, and optimize\n" + " for 4th-root error. If an alpha channel is present, it is\n" + " assumed to be HDR and optimized for 4th-root error as well.\n" + " Equivalent to\n" + " \"-forcehdr_rgba -v 0 0.75 0 1 0 0 -va 0.75 0 1 0 -dblimit 999\"\n" + "\n" + " -hdr_log\n" + " -hdra_log\n" + " Assume that the input texture is an HDR texture, and optimize\n" + " for logarithmic error. This should give better results than -hdr\n" + " on metrics like \"logRMSE\" and \"mPSNR\", but the subjective\n" + " quality (in particular block artifacts) is generally significantly worse\n" + " than -hdr.\n" + " \"-hdr_log\" is equivalent to\n" + " \"-forcehdr_rgb -v 0 1 0 1 0 0 -va 0.02 1 0 0 -dblimit 999\"\n" + " \"-hdra_log\" is equivalent to\n" + " \"-forcehdr_rgba -v 0 1 0 1 0 0 -va 1 0 1 0 -dblimit 999\"\n" + "\n" + "\n" + "\n" + "Performance-quality tradeoff presets:\n" + "-------------------------------------\n" + "These are presets that provide different tradeoffs between encoding\n" + "performance and quality. Exactly one of these presets has to be specified\n" + "for encoding; if this is not done, the codec reports an error message.\n" + "\n" + " -veryfast\n" + " Run codec in very-fast-mode; this generally results in substantial\n" + " quality loss.\n" + "\n" + " -fast\n" + " Run codec in fast-mode. This generally results in mild quality loss.\n" + "\n" + " -medium\n" + " Run codec in medium-speed-mode.\n" + "\n" + " -thorough\n" + " Run codec in thorough-mode. This should be sufficient to fix most\n" + " cases where \"-medium\" provides inadequate quality.\n" + "\n" + " -exhaustive\n" + " Run codec in exhaustive-mode. This usually produces only\n" + " marginally better quality than \"-thorough\" while considerably\n" + " increasing encode time.\n" + "\n" + "\n" + "Low-level error weighting options:\n" + "----------------------------------\n" + "These options provide low-level control of the error-weighting options\n" + "that the codec provides.\n" + "\n" + " -v \n" + " Compute the per-texel relative error weighting for the RGB color\n" + " channels as follows:\n" + "\n" + " weight = 1 / ( + \n" + " * average^2 + * stdev^2)\n" + "\n" + " The average and stdev are computed as the average-value and the\n" + " standard deviation across a neighborhood of each texel; the \n" + " argument specifies how wide this neighborhood should be.\n" + " If this option is given without -va, it affects the weighting of RGB\n" + " color components only, while alpha is assigned the weight 1.0 .\n" + "\n" + " The parameter is used to control the degree of mixing\n" + " between color channels. Setting this parameter to 0 causes the average\n" + " and stdev computation to be done completely separately for each color\n" + " channel; setting it to 1 causes the results from the red, green and\n" + " blue color channel to be combined into a single result that is applied\n" + " to all three channels. It is possible to set the mixing factor\n" + " to a value between 0 and 1 in order to obtain a result in-between.\n" + "\n" + " The argument is a power used to raise the values of the input\n" + " pixels before computing average and stdev; e.g. a power of 0.5 causes\n" + " the codec to take the square root of every input pixel value before\n" + " computing the averages and standard deviations.\n" + "\n" + " -va \n" + " Used together with -v; it computes a relative per-texel\n" + " weighting for the alpha component based on average and standard\n" + " deviation in the same manner as described for -v, but with its own\n" + " , , and parameters.\n" + "\n" + " -a \n" + " For textures with alpha channel, scale per-texel weights by\n" + " alpha. The alpha value chosen for scaling of any particular texel\n" + " is taken as an average across a neighborhood of the texel.\n" + " The argument gives the radius of this neighborhood;\n" + " a radius of 0 causes the texel's own alpha value to be used with\n" + " no contribution from neighboring texels.\n" + "\n" + " -ch \n" + " Assign relative weight to each color channel.\n" + " If this option is combined with any of the other options above,\n" + " the other options are used to compute a weighting, then the \n" + " weigthing is multiplied by the weighting provided by this argument.\n" + "\n" + " -rn\n" + " Assume that the red and alpha color channels (after swizzle)\n" + " represent the X and Y components for a normal map,\n" + " and scale the error weighting so as to match angular error as closely\n" + " as possible. The reconstruction function for the Z component\n" + " is assumed to be Z=sqrt(1 - X^2 - X^2).\n" + "\n" + " -b \n" + " Increase error weight for texels at compression-block edges\n" + " and corners; the parameter specifies how much the weights are to be\n" + " modified, with 0 giving no modification. Higher values should reduce\n" + " block-artifacts, at the cost of worsening other artifacts.\n" + "\n" + "\n" + "Low-level performance-quality tradeoff options:\n" + "-----------------------------------------------\n" + "These options provide low-level control of the performance-quality tradeoffs\n" + "that the codec provides.\n" + "\n" + " -plimit \n" + " Test only different partitionings. Higher numbers give better\n" + " quality at the expense of longer encode time; however large values tend\n" + " to give diminishing returns. This parameter can be set to a\n" + " number from 1 to %d. By default, this limit is set based on the active\n" + " preset, as follows:\n" + " -veryfast : 2\n" + " -fast : 4\n" + " -medium : 25\n" + " -thorough : 100\n" + " -exhaustive : %d\n" + "\n" + " -dblimit \n" + " Stop compression work on a block as soon as the PSNR of the block,\n" + " as measured in dB, exceeds this limit. Higher numbers give better\n" + " quality at the expense of longer encode times. If not set explicitly,\n" + " it is set based on the currently-active block size and preset, as listed\n" + " below (where N is the number of texels per block):\n" + "\n" + " -veryfast : dblimit = MAX( 53-19*log10(N), 70-35*log10(N) )\n" + " -fast : dblimit = MAX( 63-19*log10(N), 85-35*log10(N) )\n" + " -medium : dblimit = MAX( 70-19*log10(N), 95-35*log10(N) )\n" + " -thorough : dblimit = MAX( 77-19*log10(N), 105-35*log10(N) )\n" + " -exhaustive : dblimit = 999\n" + "\n" + " Note that the compressor is not actually guaranteed to reach these PSNR\n" + " numbers for any given block; also, at the point where the compressor\n" + " discovers that it has exceeded the dblimit, it may have exceeded it by\n" + " a large amount, so it is still possible to get a PSNR value that is\n" + " substantially higher than the dblimit would suggest.\n" + "\n" + " This option is ineffective for HDR textures.\n" + "\n" + " -oplimit \n" + " If the error term from encoding with 2 partitions is greater than the\n" + " error term from encoding with 1 partition by more than the specified\n" + " factor, then cut compression work short.\n" + " By default, this factor is set based on the active preset, as follows:\n" + " -veryfast : 1.0\n" + " -fast : 1.0\n" + " -medium : 1.2\n" + " -thorough : 2.5\n" + " -exhaustive : 1000\n" + " The codec will not apply this factor if the input texture is a normal\n" + " map (content resembles a normal-map, or one of the -normal_* presets\n" + " is used).\n" + "\n" + " -mincorrel \n" + " For each block, the codec will compute the correlation coefficients\n" + " between any two color components; if no pair of colors have a\n" + " correlation coefficient below the cutoff specified by this switch,\n" + " the codec will abstain from trying the dual-weight-planes.\n" + " By default, this factor is set based on the active preset, as follows:\n" + " -veryfast : 0.5\n" + " -fast : 0.5\n" + " -medium : 0.75\n" + " -thorough : 0.95\n" + " -exhaustive : 0.99\n" + " If the input texture is a normal-map (content resembles a normal-map\n" + " or one of the -normal_* presets are used) the codec will use a value\n" + " of 0.99.\n" + "\n" + " -bmc \n" + " Cutoff on the set of block modes to use; the cutoff is a percentile\n" + " of the block modes that are most commonly used. The value takes a value\n" + " from 0 to 100, where 0 offers the highest speed and lowest quality,\n" + " and 100 offers the highest quality and lowest speed.\n" + " By default, this factor is set based on the active preset, as follows:\n" + " -veryfast : 25\n" + " -fast : 50\n" + " -medium : 75\n" + " -thorough : 95\n" + " -exhaustive : 100\n" + " This option is ineffective for 3D textures.\n" + "\n" + " -maxiters \n" + " Maximum number of refinement iterations to apply to colors and weights.\n" + " Minimum value is 1; larger values give slight quality increase\n" + " at expense of mild performance loss. By default, the iteration count is\n" + " picked based on the active preset, as follows:\n" + " -veryfast : 1\n" + " -fast : 1\n" + " -medium : 2\n" + " -thorough : 4\n" + " -exhaustive : 4\n" + "\n" + "\n" + "\n" + "Other options:\n" + "--------------\n" + "\n" + " -array \n" + " Loads a an array of 2D image slices as a 3D image. The filename given\n" + " is used as a base, and decorated with _0, _1, up to _ prior\n" + " to loading each slice. So -array 3 input.png would load input_0.png,\n" + " input_1.png and input_2.png as slices at z=0,1,2 respectively.\n" + "\n" + " -forcehdr_rgb\n" + " Force the use of HDR endpoint modes. By default, only LDR endpoint\n" + " modes are used. If alpha is present, alpha is kept as LDR.\n" + " -forcehdr_rgba\n" + " Force the use of HDR endpoint modes. By default, only LDR endpoint\n" + " modes are used. If alpha is present, alpha is forced into HDR as well.\n" + "\n" + " -esw \n" + " Swizzle the color components before encoding. The swizzle pattern\n" + " is specified as a 4-character string, where the characters specify\n" + " which color component will end up in the Red, Green, Blue and Alpha\n" + " channels before encoding takes place. The characters may be taken\n" + " from the set (r,g,b,a,0,1), where r,g,b,a use color components from\n" + " the input texture and 0,1 use the constant values 0 and 1.\n" + "\n" + " As an example, if you have an input RGBA texture where you wish to\n" + " switch around the R and G channels, as well as replacing the\n" + " alpha channel with the constant value 1, a suitable swizzle\n" + " option would be:\n" + " -esw grb1\n" + " Note that if -esw is used together with any of the\n" + " error weighting functions, the swizzle is considered to be\n" + " applied before the error weighting function.\n" + "\n" + " -dsw \n" + " Swizzle pattern to apply after decoding a texture. This pattern is\n" + " specified in the samw way as the pre-encoding swizzle pattern\n" + " for the -sw switch. However, one additional character is supported,\n" + " namely 'z' for constructing the third component of a normal map.\n" + "\n" + " -srgb\n" + " Convert input image from sRGB to linear-RGB before encode; convert\n" + " output image from linear-RGB to sRGB after decode. For encode, the\n" + " transform is applied after swizzle; for decode, the transform\n" + " is applied before swizzle.\n" + "\n" + " -j \n" + " Run encoding with multithreading, using the specified number\n" + " of threads. If not specified, the codec will autodetect the\n" + " number of available logical CPUs and spawn one thread for each.\n" + " Use \"-j 1\" if you wish to run the codec in single-thread mode.\n" + "\n" + " -silentmode\n" + " Suppresses all output from the codec, except in case of errors.\n" + " If this switch is not provided, the codec will display the encoding\n" + " settings it uses and show a progress counter during encode.\n" + "\n" + " -time\n" + " Displays time taken for entire run, together with time taken for\n" + " coding step only. If requested, this is output even in -silentmode.\n" + "\n" + " -showpsnr\n" + " In test mode (-t), displays PSNR difference between input and output\n" + " images, in dB, even if -silentmode is specified. Works for LDR images\n" + " only.\n" + "\n" + " -mpsnr \n" + " Set the low and high f-stop values to use for the mPSNR error metric.\n" + " Default is low=-10, high=10.\n" + " The mPSNR error metric only applies to HDR textures.\n" + " This option can be used together with -compare .\n" + "\n" + "\n" + "\n" + "Tips & tricks:\n" + "--------------" + "\n" + "ASTC, being a block-based format, is moderately prone to block artifacts.\n" + "If block artifacts are a problem when compressing a given texture,\n" + "adding some or all of following command-line options may help:\n" + " -b 1.8\n" + " -v 2 1 1 0 25 0.1\n" + " -va 1 1 0 25\n" + " -dblimit 60\n" + "The -b option is a general-purpose block-artifact reduction option. The\n" + "-v and -va options concentrate effort where smooth regions lie next to regions\n" + "with high detail (such regions are particularly prone to block artifacts\n" + "otherwise). The -dblimit option is sometimes also needed to reduce\n" + "block artifacts in regions with very smooth gradients.\n" + "\n" + "If a texture exhibits severe block artifacts in only some, but not all, of\n" + "the color channels (common problem with mask textures), then it may help\n" + "to use the -ch option to raise the weighting of the affected color channel(s).\n" + "For example, if the green color channel in particular suffers from block\n" + "artifacts, then using the commandline option\n" + " -ch 1 6 1 1\n" + "should improve the result significantly.\n" + + , argv[0], argv[0], argv[0], argv[0], PARTITION_COUNT, PARTITION_COUNT); + + exit(1); + } + + + astc_decode_mode decode_mode = DECODE_HDR; + int opmode; // 0=compress, 1=decompress, 2=do both, 4=compare + if (!strcmp(argv[1], "-c")) + { + opmode = 0; + decode_mode = DECODE_HDR; + } + else if (!strcmp(argv[1], "-d")) + { + opmode = 1; + decode_mode = DECODE_HDR; + } + else if (!strcmp(argv[1], "-t")) + { + opmode = 2; + decode_mode = DECODE_HDR; + } + else if (!strcmp(argv[1], "-cs")) + { + opmode = 0; + decode_mode = DECODE_LDR_SRGB; + } + else if (!strcmp(argv[1], "-ds")) + { + opmode = 1; + decode_mode = DECODE_LDR_SRGB; + } + else if (!strcmp(argv[1], "-ts")) + { + opmode = 2; + decode_mode = DECODE_LDR_SRGB; + } + else if (!strcmp(argv[1], "-cl")) + { + opmode = 0; + decode_mode = DECODE_LDR; + } + else if (!strcmp(argv[1], "-dl")) + { + opmode = 1; + decode_mode = DECODE_LDR; + } + else if (!strcmp(argv[1], "-tl")) + { + opmode = 2; + decode_mode = DECODE_LDR; + } + else if (!strcmp(argv[1], "-compare")) + { + opmode = 4; + decode_mode = DECODE_HDR; + } + else + { + printf("Unrecognized operation\n"); + exit(1); + } + + int array_size = 1; + + const char *input_filename = argv[2]; + const char *output_filename = argv[3]; + + int silentmode = 0; + int timemode = 0; + int psnrmode = 0; + + error_weighting_params ewp; + + ewp.rgb_power = 1.0f; + ewp.alpha_power = 1.0f; + ewp.rgb_base_weight = 1.0f; + ewp.alpha_base_weight = 1.0f; + ewp.rgb_mean_weight = 0.0f; + ewp.rgb_stdev_weight = 0.0f; + ewp.alpha_mean_weight = 0.0f; + ewp.alpha_stdev_weight = 0.0f; + + ewp.rgb_mean_and_stdev_mixing = 0.0f; + ewp.mean_stdev_radius = 0; + ewp.enable_rgb_scale_with_alpha = 0; + ewp.alpha_radius = 0; + + ewp.block_artifact_suppression = 0.0f; + ewp.rgba_weights[0] = 1.0f; + ewp.rgba_weights[1] = 1.0f; + ewp.rgba_weights[2] = 1.0f; + ewp.rgba_weights[3] = 1.0f; + ewp.ra_normal_angular_scale = 0; + + swizzlepattern swz_encode = { 0, 1, 2, 3 }; + swizzlepattern swz_decode = { 0, 1, 2, 3 }; + + + int thread_count = 0; // default value + int thread_count_autodetected = 0; + + int preset_has_been_set = 0; + + int plimit_autoset = -1; + int plimit_user_specified = -1; + int plimit_set_by_user = 0; + + float dblimit_autoset_2d = 0.0; + float dblimit_autoset_3d = 0.0; + float dblimit_user_specified = 0.0; + int dblimit_set_by_user = 0; + + float oplimit_autoset = 0.0; + float oplimit_user_specified = 0.0; + int oplimit_set_by_user = 0; + + float mincorrel_autoset = 0.0; + float mincorrel_user_specified = 0.0; + int mincorrel_set_by_user = 0; + + float bmc_user_specified = 0.0; + float bmc_autoset = 0.0; + int bmc_set_by_user = 0; + + int maxiters_user_specified = 0; + int maxiters_autoset = 0; + int maxiters_set_by_user = 0; + + int pcdiv = 1; + + int xdim_2d = 0; + int ydim_2d = 0; + int xdim_3d = 0; + int ydim_3d = 0; + int zdim_3d = 0; + + int target_bitrate_set = 0; + float target_bitrate = 0; + + int print_block_mode_histogram = 0; + + float log10_texels_2d = 0.0f; + float log10_texels_3d = 0.0f; + + int low_fstop = -10; + int high_fstop = 10; + + + // parse the command line's encoding options. + int argidx; + if (opmode == 0 || opmode == 2) + { + if (argc < 5) + { + printf("Cannot encode without specifying blocksize\n"); + exit(1); + } + + if (strchr(argv[4], '.') != NULL) + { + target_bitrate = static_cast < float >(atof(argv[4])); + target_bitrate_set = 1; + find_closest_blockdim_2d(target_bitrate, &xdim_2d, &ydim_2d, DEBUG_ALLOW_ILLEGAL_BLOCK_SIZES); + find_closest_blockdim_3d(target_bitrate, &xdim_3d, &ydim_3d, &zdim_3d, DEBUG_ALLOW_ILLEGAL_BLOCK_SIZES); + } + + else + { + int dimensions = sscanf(argv[4], "%dx%dx%d", &xdim_3d, &ydim_3d, &zdim_3d); + switch (dimensions) + { + case 0: + case 1: + // failed to parse the blocksize argument at all. + printf("Blocksize not specified\n"); + exit(1); + case 2: + { + zdim_3d = 1; + + // Check 2D constraints + if(!(xdim_3d ==4 || xdim_3d == 5 || xdim_3d == 6 || xdim_3d == 8 || xdim_3d == 10 || xdim_3d == 12) || + !(ydim_3d ==4 || ydim_3d == 5 || ydim_3d == 6 || ydim_3d == 8 || ydim_3d == 10 || ydim_3d == 12) ) + { + printf("Block dimensions %d x %d unsupported\n", xdim_3d, ydim_3d); + exit(1); + } + + int is_legal_2d = (xdim_3d==ydim_3d) || (xdim_3d==ydim_3d+1) || ((xdim_3d==ydim_3d+2) && !(xdim_3d==6 && ydim_3d==4)) || + (xdim_3d==8 && ydim_3d==5) || (xdim_3d==10 && ydim_3d==5) || (xdim_3d==10 && ydim_3d==6); + + if(!DEBUG_ALLOW_ILLEGAL_BLOCK_SIZES && !is_legal_2d) + { + printf("Block dimensions %d x %d disallowed\n", xdim_3d, ydim_3d); + exit(1); + } + } + break; + + default: + { + // Check 3D constraints + if(xdim_3d < 3 || xdim_3d > 6 || ydim_3d < 3 || ydim_3d > 6 || zdim_3d < 3 || zdim_3d > 6) + { + printf("Block dimensions %d x %d x %d unsupported\n", xdim_3d, ydim_3d, zdim_3d); + exit(1); + } + + int is_legal_3d = ((xdim_3d==ydim_3d)&&(ydim_3d==zdim_3d)) || ((xdim_3d==ydim_3d+1)&&(ydim_3d==zdim_3d)) || ((xdim_3d==ydim_3d)&&(ydim_3d==zdim_3d+1)); + + if(!DEBUG_ALLOW_ILLEGAL_BLOCK_SIZES && !is_legal_3d) + { + printf("Block dimensions %d x %d x %d disallowed\n", xdim_3d, ydim_3d, zdim_3d); + exit(1); + } + } + break; + } + + xdim_2d = xdim_3d; + ydim_2d = ydim_3d; + } + + log10_texels_2d = log((float)(xdim_2d * ydim_2d)) / log(10.0f); + log10_texels_3d = log((float)(xdim_3d * ydim_3d * zdim_3d)) / log(10.0f); + argidx = 5; + } + else + { + // for decode and comparison, block size is not needed. + argidx = 4; + } + + + while (argidx < argc) + { + if (!strcmp(argv[argidx], "-silentmode")) + { + argidx++; + silentmode = 1; + suppress_progress_counter = 1; + } + else if (!strcmp(argv[argidx], "-time")) + { + argidx++; + timemode = 1; + } + else if (!strcmp(argv[argidx], "-showpsnr")) + { + argidx++; + psnrmode = 1; + } + else if (!strcmp(argv[argidx], "-v")) + { + argidx += 7; + if (argidx > argc) + { + printf("-v switch with less than 6 arguments, quitting\n"); + exit(1); + } + ewp.mean_stdev_radius = atoi(argv[argidx - 6]); + ewp.rgb_power = static_cast < float >(atof(argv[argidx - 5])); + ewp.rgb_base_weight = static_cast < float >(atof(argv[argidx - 4])); + ewp.rgb_mean_weight = static_cast < float >(atof(argv[argidx - 3])); + ewp.rgb_stdev_weight = static_cast < float >(atof(argv[argidx - 2])); + ewp.rgb_mean_and_stdev_mixing = static_cast < float >(atof(argv[argidx - 1])); + } + else if (!strcmp(argv[argidx], "-va")) + { + argidx += 5; + if (argidx > argc) + { + printf("-va switch with less than 4 arguments, quitting\n"); + exit(1); + } + ewp.alpha_power = static_cast < float >(atof(argv[argidx - 5])); + ewp.alpha_base_weight = static_cast < float >(atof(argv[argidx - 3])); + ewp.alpha_mean_weight = static_cast < float >(atof(argv[argidx - 2])); + ewp.alpha_stdev_weight = static_cast < float >(atof(argv[argidx - 1])); + } + else if (!strcmp(argv[argidx], "-ch")) + { + argidx += 5; + if (argidx > argc) + { + printf("-ch switch with less than 4 arguments\n"); + exit(1); + } + ewp.rgba_weights[0] = static_cast < float >(atof(argv[argidx - 4])); + ewp.rgba_weights[1] = static_cast < float >(atof(argv[argidx - 3])); + ewp.rgba_weights[2] = static_cast < float >(atof(argv[argidx - 2])); + ewp.rgba_weights[3] = static_cast < float >(atof(argv[argidx - 1])); + } + else if (!strcmp(argv[argidx], "-a")) + { + argidx += 2; + if (argidx > argc) + { + printf("-a switch with no argument\n"); + exit(1); + } + ewp.enable_rgb_scale_with_alpha = 1; + ewp.alpha_radius = atoi(argv[argidx - 1]); + } + else if (!strcmp(argv[argidx], "-rn")) + { + argidx++; + ewp.ra_normal_angular_scale = 1; + } + + else if (!strcmp(argv[argidx], "-b")) + { + argidx += 2; + if (argidx > argc) + { + printf("-b switch with no argument\n"); + exit(1); + } + ewp.block_artifact_suppression = static_cast < float >(atof(argv[argidx - 1])); + } + + else if (!strcmp(argv[argidx], "-esw")) + { + argidx += 2; + if (argidx > argc) + { + printf("-esw switch with no argument\n"); + exit(1); + } + if (strlen(argv[argidx - 1]) != 4) + { + printf("Swizzle pattern for the -esw switch must have exactly 4 characters\n"); + exit(1); + } + int swizzle_components[4]; + for (i = 0; i < 4; i++) + switch (argv[argidx - 1][i]) + { + case 'r': + swizzle_components[i] = 0; + break; + case 'g': + swizzle_components[i] = 1; + break; + case 'b': + swizzle_components[i] = 2; + break; + case 'a': + swizzle_components[i] = 3; + break; + case '0': + swizzle_components[i] = 4; + break; + case '1': + swizzle_components[i] = 5; + break; + default: + printf("Character '%c' is not a valid swizzle-character\n", argv[argidx - 1][i]); + exit(1); + } + swz_encode.r = swizzle_components[0]; + swz_encode.g = swizzle_components[1]; + swz_encode.b = swizzle_components[2]; + swz_encode.a = swizzle_components[3]; + } + + else if (!strcmp(argv[argidx], "-dsw")) + { + argidx += 2; + if (argidx > argc) + { + printf("-dsw switch with no argument\n"); + exit(1); + } + if (strlen(argv[argidx - 1]) != 4) + { + printf("Swizzle pattern for the -dsw switch must have exactly 4 characters\n"); + exit(1); + } + int swizzle_components[4]; + for (i = 0; i < 4; i++) + switch (argv[argidx - 1][i]) + { + case 'r': + swizzle_components[i] = 0; + break; + case 'g': + swizzle_components[i] = 1; + break; + case 'b': + swizzle_components[i] = 2; + break; + case 'a': + swizzle_components[i] = 3; + break; + case '0': + swizzle_components[i] = 4; + break; + case '1': + swizzle_components[i] = 5; + break; + case 'z': + swizzle_components[i] = 6; + break; + default: + printf("Character '%c' is not a valid swizzle-character\n", argv[argidx - 1][i]); + exit(1); + } + swz_decode.r = swizzle_components[0]; + swz_decode.g = swizzle_components[1]; + swz_decode.b = swizzle_components[2]; + swz_decode.a = swizzle_components[3]; + } + + + // presets begin here + else if (!strcmp(argv[argidx], "-normal_psnr")) + { + argidx++; + ewp.rgba_weights[0] = 1.0f; + ewp.rgba_weights[1] = 0.0f; + ewp.rgba_weights[2] = 0.0f; + ewp.rgba_weights[3] = 1.0f; + ewp.ra_normal_angular_scale = 1; + swz_encode.r = 0; // r <- red + swz_encode.g = 0; // g <- red + swz_encode.b = 0; // b <- red + swz_encode.a = 1; // a <- green + swz_decode.r = 0; // r <- red + swz_decode.g = 3; // g <- alpha + swz_decode.b = 6; // b <- reconstruct + swz_decode.a = 5; // 1.0 + + oplimit_user_specified = 1000.0f; + oplimit_set_by_user = 1; + mincorrel_user_specified = 0.99f; + mincorrel_set_by_user = 1; + } + + else if (!strcmp(argv[argidx], "-normal_percep")) + { + argidx++; + ewp.rgba_weights[0] = 1.0f; + ewp.rgba_weights[1] = 0.0f; + ewp.rgba_weights[2] = 0.0f; + ewp.rgba_weights[3] = 1.0f; + ewp.ra_normal_angular_scale = 1; + swz_encode.r = 0; // r <- red + swz_encode.g = 0; // g <- red + swz_encode.b = 0; // b <- red + swz_encode.a = 1; // a <- green + swz_decode.r = 0; // r <- red + swz_decode.g = 3; // g <- alpha + swz_decode.b = 6; // b <- reconstruct + swz_decode.a = 5; // 1.0 + + oplimit_user_specified = 1000.0f; + oplimit_set_by_user = 1; + mincorrel_user_specified = 0.99f; + mincorrel_set_by_user = 1; + + dblimit_user_specified = 999; + dblimit_set_by_user = 1; + + ewp.block_artifact_suppression = 1.8f; + ewp.mean_stdev_radius = 3; + ewp.rgb_mean_weight = 0; + ewp.rgb_stdev_weight = 50; + ewp.rgb_mean_and_stdev_mixing = 0.0; + ewp.alpha_mean_weight = 0; + ewp.alpha_stdev_weight = 50; + } + + + else if (!strcmp(argv[argidx], "-mask")) + { + argidx++; + ewp.mean_stdev_radius = 3; + ewp.rgb_mean_weight = 0.0f; + ewp.rgb_stdev_weight = 25.0f; + ewp.rgb_mean_and_stdev_mixing = 0.03f; + ewp.alpha_mean_weight = 0.0f; + ewp.alpha_stdev_weight = 25.0f; + } + + else if (!strcmp(argv[argidx], "-alphablend")) + { + argidx++; + ewp.enable_rgb_scale_with_alpha = 1; + ewp.alpha_radius = 1; + } + + else if (!strcmp(argv[argidx], "-hdra")) + { + if(decode_mode != DECODE_HDR) + { + printf("The option -hdra is only available in HDR mode\n"); + exit(1); + } + + argidx++; + ewp.mean_stdev_radius = 0; + ewp.rgb_power = 0.75; + ewp.rgb_base_weight = 0; + ewp.rgb_mean_weight = 1; + ewp.alpha_power = 0.75; + ewp.alpha_base_weight = 0; + ewp.alpha_mean_weight = 1; + rgb_force_use_of_hdr = 1; + alpha_force_use_of_hdr = 1; + dblimit_user_specified = 999; + dblimit_set_by_user = 1; + } + + else if (!strcmp(argv[argidx], "-hdr")) + { + if(decode_mode != DECODE_HDR) + { + printf("The option -hdr is only available in HDR mode\n"); + exit(1); + } + + argidx++; + ewp.mean_stdev_radius = 0; + ewp.rgb_power = 0.75; + ewp.rgb_base_weight = 0; + ewp.rgb_mean_weight = 1; + ewp.alpha_base_weight = 0.05f; + rgb_force_use_of_hdr = 1; + alpha_force_use_of_hdr = 0; + dblimit_user_specified = 999; + dblimit_set_by_user = 1; + } + + else if (!strcmp(argv[argidx], "-hdra_log")) + { + if(decode_mode != DECODE_HDR) + { + printf("The option -hdra_log is only available in HDR mode\n"); + exit(1); + } + + argidx++; + ewp.mean_stdev_radius = 0; + ewp.rgb_power = 1; + ewp.rgb_base_weight = 0; + ewp.rgb_mean_weight = 1; + ewp.alpha_power = 1; + ewp.alpha_base_weight = 0; + ewp.alpha_mean_weight = 1; + rgb_force_use_of_hdr = 1; + alpha_force_use_of_hdr = 1; + dblimit_user_specified = 999; + dblimit_set_by_user = 1; + } + + else if (!strcmp(argv[argidx], "-hdr_log")) + { + argidx++; + ewp.mean_stdev_radius = 0; + ewp.rgb_power = 1; + ewp.rgb_base_weight = 0; + ewp.rgb_mean_weight = 1; + ewp.alpha_base_weight = 0.05f; + rgb_force_use_of_hdr = 1; + alpha_force_use_of_hdr = 0; + dblimit_user_specified = 999; + dblimit_set_by_user = 1; + } + + + // presets end here + + else if (!strcmp(argv[argidx], "-forcehdr_rgb")) + { + if(decode_mode != DECODE_HDR) + { + printf("The option -forcehdr_rgb is only available in HDR mode\n"); + exit(1); + } + + argidx++; + rgb_force_use_of_hdr = 1; + } + + else if (!strcmp(argv[argidx], "-forcehdr_rgba")) + { + if(decode_mode != DECODE_HDR) + { + printf("The option -forcehdr_rgbs is only available in HDR mode\n"); + exit(1); + } + + argidx++; + rgb_force_use_of_hdr = 1; + alpha_force_use_of_hdr = 1; + } + + else if (!strcmp(argv[argidx], "-bmc")) + { + argidx += 2; + if (argidx > argc) + { + printf("-bmc switch with no argument\n"); + exit(1); + } + float cutoff = (float)atof(argv[argidx - 1]); + if (cutoff > 100 || !(cutoff >= 0)) + cutoff = 100; + bmc_user_specified = cutoff; + bmc_set_by_user = 1; + } + + else if (!strcmp(argv[argidx], "-plimit")) + { + argidx += 2; + if (argidx > argc) + { + printf("-plimit switch with no argument\n"); + exit(1); + } + plimit_user_specified = atoi(argv[argidx - 1]); + plimit_set_by_user = 1; + } + else if (!strcmp(argv[argidx], "-dblimit")) + { + argidx += 2; + if (argidx > argc) + { + printf("-dblimit switch with no argument\n"); + exit(1); + } + dblimit_user_specified = static_cast < float >(atof(argv[argidx - 1])); + dblimit_set_by_user = 1; + } + else if (!strcmp(argv[argidx], "-oplimit")) + { + argidx += 2; + if (argidx > argc) + { + printf("-oplimit switch with no argument\n"); + exit(1); + } + oplimit_user_specified = static_cast < float >(atof(argv[argidx - 1])); + oplimit_set_by_user = 1; + } + else if (!strcmp(argv[argidx], "-mincorrel")) + { + argidx += 2; + if (argidx > argc) + { + printf("-mincorrel switch with no argument\n"); + exit(1); + } + mincorrel_user_specified = static_cast < float >(atof(argv[argidx - 1])); + mincorrel_set_by_user = 1; + } + else if (!strcmp(argv[argidx], "-maxiters")) + { + argidx += 2; + if (argidx > argc) + { + printf("-maxiters switch with no argument\n"); + exit(1); + } + maxiters_user_specified = atoi(argv[argidx - 1]); + maxiters_set_by_user = 1; + } + + + else if (!strcmp(argv[argidx], "-veryfast")) + { + argidx++; + plimit_autoset = 2; + oplimit_autoset = 1.0; + dblimit_autoset_2d = MAX(70 - 35 * log10_texels_2d, 53 - 19 * log10_texels_2d); + dblimit_autoset_3d = MAX(70 - 35 * log10_texels_3d, 53 - 19 * log10_texels_3d); + bmc_autoset = 25; + mincorrel_autoset = 0.5; + maxiters_autoset = 1; + + switch (ydim_2d) + { + case 4: + pcdiv = 240; + break; + case 5: + pcdiv = 56; + break; + case 6: + pcdiv = 64; + break; + case 8: + pcdiv = 47; + break; + case 10: + pcdiv = 36; + break; + case 12: + pcdiv = 30; + break; + default: + pcdiv = 30; + break; + } + preset_has_been_set++; + } + + else if (!strcmp(argv[argidx], "-fast")) + { + argidx++; + plimit_autoset = 4; + oplimit_autoset = 1.0; + mincorrel_autoset = 0.5; + dblimit_autoset_2d = MAX(85 - 35 * log10_texels_2d, 63 - 19 * log10_texels_2d); + dblimit_autoset_3d = MAX(85 - 35 * log10_texels_3d, 63 - 19 * log10_texels_3d); + bmc_autoset = 50; + maxiters_autoset = 1; + + + switch (ydim_2d) + { + case 4: + pcdiv = 60; + break; + case 5: + pcdiv = 27; + break; + case 6: + pcdiv = 30; + break; + case 8: + pcdiv = 24; + break; + case 10: + pcdiv = 16; + break; + case 12: + pcdiv = 20; + break; + default: + pcdiv = 20; + break; + }; + preset_has_been_set++; + } + else if (!strcmp(argv[argidx], "-medium")) + { + argidx++; + plimit_autoset = 25; + oplimit_autoset = 1.2f; + mincorrel_autoset = 0.75f; + dblimit_autoset_2d = MAX(95 - 35 * log10_texels_2d, 70 - 19 * log10_texels_2d); + dblimit_autoset_3d = MAX(95 - 35 * log10_texels_3d, 70 - 19 * log10_texels_3d); + bmc_autoset = 75; + maxiters_autoset = 2; + + switch (ydim_2d) + { + case 4: + pcdiv = 25; + break; + case 5: + pcdiv = 15; + break; + case 6: + pcdiv = 15; + break; + case 8: + pcdiv = 10; + break; + case 10: + pcdiv = 8; + break; + case 12: + pcdiv = 6; + break; + default: + pcdiv = 6; + break; + }; + preset_has_been_set++; + } + else if (!strcmp(argv[argidx], "-thorough")) + { + argidx++; + plimit_autoset = 100; + oplimit_autoset = 2.5f; + mincorrel_autoset = 0.95f; + dblimit_autoset_2d = MAX(105 - 35 * log10_texels_2d, 77 - 19 * log10_texels_2d); + dblimit_autoset_3d = MAX(105 - 35 * log10_texels_3d, 77 - 19 * log10_texels_3d); + bmc_autoset = 95; + maxiters_autoset = 4; + + switch (ydim_2d) + { + case 4: + pcdiv = 12; + break; + case 5: + pcdiv = 7; + break; + case 6: + pcdiv = 7; + break; + case 8: + pcdiv = 5; + break; + case 10: + pcdiv = 4; + break; + case 12: + pcdiv = 3; + break; + default: + pcdiv = 3; + break; + }; + preset_has_been_set++; + } + else if (!strcmp(argv[argidx], "-exhaustive")) + { + argidx++; + plimit_autoset = PARTITION_COUNT; + oplimit_autoset = 1000.0f; + mincorrel_autoset = 0.99f; + dblimit_autoset_2d = 999.0f; + dblimit_autoset_3d = 999.0f; + bmc_autoset = 100; + maxiters_autoset = 4; + + preset_has_been_set++; + switch (ydim_2d) + { + case 4: + pcdiv = 3; + break; + case 5: + pcdiv = 1; + break; + case 6: + pcdiv = 1; + break; + case 8: + pcdiv = 1; + break; + case 10: + pcdiv = 1; + break; + case 12: + pcdiv = 1; + break; + default: + pcdiv = 1; + break; + } + } + else if (!strcmp(argv[argidx], "-j")) + { + argidx += 2; + if (argidx > argc) + { + printf("-j switch with no argument\n"); + exit(1); + } + thread_count = atoi(argv[argidx - 1]); + } + + else if (!strcmp(argv[argidx], "-srgb")) + { + argidx++; + perform_srgb_transform = 1; + dblimit_user_specified = 60; + dblimit_set_by_user = 1; + } + + else if (!strcmp(argv[argidx], "-mpsnr")) + { + argidx += 3; + if (argidx > argc) + { + printf("-mpsnr switch with less than 2 arguments\n"); + exit(1); + } + low_fstop = atoi(argv[argidx - 2]); + high_fstop = atoi(argv[argidx - 1]); + if (high_fstop < low_fstop) + { + printf("For -mpsnr switch, the argument cannot be greater than the\n" "high argument.\n"); + exit(1); + } + } + + else if (!strcmp(argv[argidx], "-diag")) + { + argidx += 2; + if (argidx > argc) + { + printf("-diag switch with no argument\n"); + exit(1); + } + + #ifdef DEBUG_PRINT_DIAGNOSTICS + diagnostics_tile = atoi(argv[argidx - 1]); + #else + printf("-diag switch given, but codec has been compiled without\n" "DEBUG_PRINT_DIAGNOSTICS enabled; please recompile.\n"); + exit(1); + #endif + } + else if (!strcmp(argv[argidx], "-bmstat")) + { + argidx++; + print_block_mode_histogram = 1; + } + else if (!strcmp(argv[argidx], "-pte")) + { + argidx++; + print_tile_errors = 1; + } + else if (!strcmp(argv[argidx], "-stats")) + { + argidx++; + print_statistics = 1; + } + + // Option: Encode a 3D image from an array of 2D images. + else if (!strcmp(argv[argidx], "-array")) + { + // Only supports compressing (not decompressing or comparison). + if (opmode != 0) + { + printf("-array switch given when not compressing files - decompression and comparison of arrays not supported.\n"); + exit(1); + } + + // Image depth must be specified. + if (argidx + 2 > argc) + { + printf("-array switch given, but no array size (image depth) given.\n"); + exit(1); + } + argidx++; + + // Read array size (image depth). + if (!sscanf(argv[argidx], "%u", &array_size) || array_size == 0) + { + printf("Invalid array size (image depth) given with -array option: \"%s\".\n", argv[argidx]); + exit(1); + } + argidx++; + } + + else + { + printf("Commandline argument \"%s\" not recognized\n", argv[argidx]); + exit(1); + } + } + + + if (opmode == 4) + { + compare_two_files(input_filename, output_filename, low_fstop, high_fstop, psnrmode); + exit(0); + } + + + float texel_avg_error_limit_2d = 0.0f; + float texel_avg_error_limit_3d = 0.0f; + + if (opmode == 0 || opmode == 2) + { + // if encode, process the parsed command line values + + if (preset_has_been_set != 1) + { + printf("For encoding, need to specify exactly one performance-quality\n" + "trade-off preset option. The available presets are:\n" " -veryfast\n" " -fast\n" " -medium\n" " -thorough\n" " -exhaustive\n"); + exit(1); + } + + progress_counter_divider = pcdiv; + + int partitions_to_test = plimit_set_by_user ? plimit_user_specified : plimit_autoset; + float dblimit_2d = dblimit_set_by_user ? dblimit_user_specified : dblimit_autoset_2d; + float dblimit_3d = dblimit_set_by_user ? dblimit_user_specified : dblimit_autoset_3d; + float oplimit = oplimit_set_by_user ? oplimit_user_specified : oplimit_autoset; + float mincorrel = mincorrel_set_by_user ? mincorrel_user_specified : mincorrel_autoset; + + int maxiters = maxiters_set_by_user ? maxiters_user_specified : maxiters_autoset; + ewp.max_refinement_iters = maxiters; + + ewp.block_mode_cutoff = (bmc_set_by_user ? bmc_user_specified : bmc_autoset) / 100.0f; + + if (rgb_force_use_of_hdr == 0) + { + texel_avg_error_limit_2d = pow(0.1f, dblimit_2d * 0.1f) * 65535.0f * 65535.0f; + texel_avg_error_limit_3d = pow(0.1f, dblimit_3d * 0.1f) * 65535.0f * 65535.0f; + } + else + { + texel_avg_error_limit_2d = 0.0f; + texel_avg_error_limit_3d = 0.0f; + } + ewp.partition_1_to_2_limit = oplimit; + ewp.lowest_correlation_cutoff = mincorrel; + + if (partitions_to_test < 1) + partitions_to_test = 1; + else if (partitions_to_test > PARTITION_COUNT) + partitions_to_test = PARTITION_COUNT; + ewp.partition_search_limit = partitions_to_test; + + // if diagnostics are run, force the thread count to 1. + if ( + #ifdef DEBUG_PRINT_DIAGNOSTICS + diagnostics_tile >= 0 || + #endif + print_tile_errors > 0 || print_statistics > 0) + { + thread_count = 1; + thread_count_autodetected = 0; + } + + if (thread_count < 1) + { + thread_count = get_number_of_cpus(); + thread_count_autodetected = 1; + } + + + // Specifying the error weight of a color component as 0 is not allowed. + // If weights are 0, then they are instead set to a small positive value. + + float max_color_component_weight = MAX(MAX(ewp.rgba_weights[0], ewp.rgba_weights[1]), + MAX(ewp.rgba_weights[2], ewp.rgba_weights[3])); + ewp.rgba_weights[0] = MAX(ewp.rgba_weights[0], max_color_component_weight / 1000.0f); + ewp.rgba_weights[1] = MAX(ewp.rgba_weights[1], max_color_component_weight / 1000.0f); + ewp.rgba_weights[2] = MAX(ewp.rgba_weights[2], max_color_component_weight / 1000.0f); + ewp.rgba_weights[3] = MAX(ewp.rgba_weights[3], max_color_component_weight / 1000.0f); + + + // print all encoding settings unless specifically told otherwise. + if (!silentmode) + { + printf("Encoding settings:\n\n"); + if (target_bitrate_set) + printf("Target bitrate provided: %.2f bpp\n", target_bitrate); + printf("2D Block size: %dx%d (%.2f bpp)\n", xdim_2d, ydim_2d, 128.0 / (xdim_2d * ydim_2d)); + printf("3D Block size: %dx%dx%d (%.2f bpp)\n", xdim_3d, ydim_3d, zdim_3d, 128.0 / (xdim_3d * ydim_3d * zdim_3d)); + printf("Radius for mean-and-stdev calculations: %d texels\n", ewp.mean_stdev_radius); + printf("RGB power: %g\n", ewp.rgb_power); + printf("RGB base-weight: %g\n", ewp.rgb_base_weight); + printf("RGB local-mean weight: %g\n", ewp.rgb_mean_weight); + printf("RGB local-stdev weight: %g\n", ewp.rgb_stdev_weight); + printf("RGB mean-and-stdev mixing across color channels: %g\n", ewp.rgb_mean_and_stdev_mixing); + printf("Alpha power: %g\n", ewp.alpha_power); + printf("Alpha base-weight: %g\n", ewp.alpha_base_weight); + printf("Alpha local-mean weight: %g\n", ewp.alpha_mean_weight); + printf("Alpha local-stdev weight: %g\n", ewp.alpha_stdev_weight); + printf("RGB weights scale with alpha: "); + if (ewp.enable_rgb_scale_with_alpha) + printf("enabled (radius=%d)\n", ewp.alpha_radius); + else + printf("disabled\n"); + printf("Color channel relative weighting: R=%g G=%g B=%g A=%g\n", ewp.rgba_weights[0], ewp.rgba_weights[1], ewp.rgba_weights[2], ewp.rgba_weights[3]); + printf("Block-artifact suppression parameter : %g\n", ewp.block_artifact_suppression); + printf("Number of distinct partitionings to test: %d (%s)\n", ewp.partition_search_limit, plimit_set_by_user ? "specified by user" : "preset"); + printf("PSNR decibel limit: 2D: %f 3D: %f (%s)\n", dblimit_2d, dblimit_3d, dblimit_set_by_user ? "specified by user" : "preset"); + printf("1->2 partition limit: %f\n", oplimit); + printf("Dual-plane color-correlation cutoff: %f (%s)\n", mincorrel, mincorrel_set_by_user ? "specified by user" : "preset"); + printf("Block Mode Percentile Cutoff: %f (%s)\n", ewp.block_mode_cutoff * 100.0f, bmc_set_by_user ? "specified by user" : "preset"); + printf("Max refinement iterations: %d (%s)\n", ewp.max_refinement_iters, maxiters_set_by_user ? "specified by user" : "preset"); + printf("Thread count : %d (%s)\n", thread_count, thread_count_autodetected ? "autodetected" : "specified by user"); + + printf("\n"); + } + + } + + + int padding = MAX(ewp.mean_stdev_radius, ewp.alpha_radius); + + // determine encoding bitness as follows: + // if enforced by the output format, follow the output format's result + // else use decode_mode to pick bitness. + int bitness = get_output_filename_enforced_bitness(output_filename); + if (bitness == -1) + { + bitness = (decode_mode == DECODE_HDR) ? 16 : 8; + } + + int xdim = -1; + int ydim = -1; + int zdim = -1; + + // Temporary image array (for merging multiple 2D images into one 3D image). + int *load_results = NULL; + astc_codec_image **input_images = NULL; + + int load_result = 0; + astc_codec_image *input_image = NULL; + astc_codec_image *output_image = NULL; + int input_components = 0; + + int input_image_is_hdr = 0; + + // load image + if (opmode == 0 || opmode == 2 || opmode == 3) + { + // Allocate arrays for image data and load results. + load_results = new int[array_size]; + input_images = new astc_codec_image *[array_size]; + + // Iterate over all input images. + for (int image_index = 0; image_index < array_size; image_index++) + { + // 2D input data. + if (array_size == 1) + { + input_images[image_index] = astc_codec_load_image(input_filename, padding, &load_results[image_index]); + } + + // 3D input data - multiple 2D images. + else + { + char new_input_filename[256]; + + // Check for extension: . + if (NULL == strrchr(input_filename, '.')) + { + printf("Unable to determine file type from extension: %s\n", input_filename); + exit(1); + } + + // Construct new file name and load: _N. + strcpy(new_input_filename, input_filename); + sprintf(strrchr(new_input_filename, '.'), "_%d%s", image_index, strrchr(input_filename, '.')); + input_images[image_index] = astc_codec_load_image(new_input_filename, padding, &load_results[image_index]); + + // Check image is not 3D. + if (input_images[image_index]->zsize != 1) + { + printf("3D source images not supported with -array option: %s\n", new_input_filename); + exit(1); + } + + // BCJ(DEBUG) + // printf("\n\n Image %d \n", image_index); + // dump_image( input_images[image_index] ); + // printf("\n\n"); + } + + // Check load result. + if (load_results[image_index] < 0) + { + printf("Failed to load image %s\n", input_filename); + exit(1); + } + + // Check format matches other slices. + if (load_results[image_index] != load_results[0]) + { + printf("Mismatching image format - image 0 and %d are a different format\n", image_index); + exit(1); + } + } + + load_result = load_results[0]; + + // Assign input image. + if (array_size == 1) + { + input_image = input_images[0]; + } + + // Merge input image data. + else + { + int i, z, xsize, ysize, zsize, bitness, slice_size; + + xsize = input_images[0]->xsize; + ysize = input_images[0]->ysize; + zsize = array_size; + bitness = (load_result & 0x80) ? 16 : 8; + slice_size = (xsize + (2 * padding)) * (ysize + (2 * padding)); + + // Allocate image memory. + input_image = allocate_image(bitness, xsize, ysize, zsize, padding); + + // Combine 2D source images into one 3D image (skip padding slices as these don't exist in 2D textures). + for (z = padding; z < zsize + padding; z++) + { + if (bitness == 8) + { + memcpy(*input_image->imagedata8[z], *input_images[z - padding]->imagedata8[0], slice_size * 4 * sizeof(uint8_t)); + } + else + { + memcpy(*input_image->imagedata16[z], *input_images[z - padding]->imagedata16[0], slice_size * 4 * sizeof(uint16_t)); + } + } + + // Clean up temporary images. + for (i = 0; i < array_size; i++) + { + destroy_image(input_images[i]); + } + input_images = NULL; + + // Clamp texels outside the actual image area. + fill_image_padding_area(input_image); + + // BCJ(DEBUG) + // dump_image( input_image ); + } + + input_components = load_result & 7; + input_image_is_hdr = (load_result & 0x80) ? 1 : 0; + + if (input_image->zsize > 1) + { + xdim = xdim_3d; + ydim = ydim_3d; + zdim = zdim_3d; + ewp.texel_avg_error_limit = texel_avg_error_limit_3d; + } + else + { + xdim = xdim_2d; + ydim = ydim_2d; + zdim = 1; + ewp.texel_avg_error_limit = texel_avg_error_limit_2d; + } + expand_block_artifact_suppression(xdim, ydim, zdim, &ewp); + + + if (!silentmode) + { + printf("%s: %dD %s image, %d x %d x %d, %d components\n\n", + input_filename, input_image->zsize > 1 ? 3 : 2, input_image_is_hdr ? "HDR" : "LDR", input_image->xsize, input_image->ysize, input_image->zsize, load_result & 7); + } + + if (padding > 0 || ewp.rgb_mean_weight != 0.0f || ewp.rgb_stdev_weight != 0.0f || ewp.alpha_mean_weight != 0.0f || ewp.alpha_stdev_weight != 0.0f) + { + if (!silentmode) + { + printf("Computing texel-neighborhood means and variances ... "); + fflush(stdout); + } + compute_averages_and_variances(input_image, ewp.rgb_power, ewp.alpha_power, ewp.mean_stdev_radius, ewp.alpha_radius, swz_encode); + if (!silentmode) + { + printf("done\n"); + fflush(stdout); + } + } + } + + + start_coding_time = get_time(); + + if (opmode == 1) + output_image = load_astc_file(input_filename, bitness, decode_mode, swz_decode); + + + // process image, if relevant + if (opmode == 2) + output_image = pack_and_unpack_astc_image(input_image, xdim, ydim, zdim, &ewp, decode_mode, swz_encode, swz_decode, bitness, thread_count); + + + end_coding_time = get_time(); + + + // print PSNR if encoding + if (opmode == 2) + { + if (psnrmode == 1) + { + compute_error_metrics(input_image_is_hdr, input_components, input_image, output_image, low_fstop, high_fstop, psnrmode); + } + } + + + // store image + if (opmode == 1 || opmode == 2) + { + int store_result = -1; + const char *format_string = ""; + + store_result = astc_codec_store_image(output_image, output_filename, bitness, &format_string); + + if (store_result < 0) + { + printf("Failed to store image %s\n", output_filename); + exit(1); + } + else + { + if (!silentmode) + { + printf("Stored %s image %s with %d color channels\n", format_string, output_filename, store_result); + } + } + } + if (opmode == 0) + { + store_astc_file(input_image, output_filename, xdim, ydim, zdim, &ewp, decode_mode, swz_encode, thread_count); + } + + + if (print_block_mode_histogram) + { + printf("%s ", argv[2]); + printf("%d %d ", xdim_2d, ydim_2d); + for (i = 0; i < 2048; i++) + printf(" %d", block_mode_histogram[i]); + printf("\n"); + } + + + end_time = get_time(); + + if (timemode) + { + printf("\nElapsed time: %.2lf seconds, of which coding time: %.2lf seconds\n", end_time - start_time, end_coding_time - start_coding_time); + } + + return 0; +} diff --git a/third_party/astcenc/Source/astc_weight_align.cpp b/third_party/astcenc/Source/astc_weight_align.cpp new file mode 100644 index 0000000000..39d1e94ba3 --- /dev/null +++ b/third_party/astcenc/Source/astc_weight_align.cpp @@ -0,0 +1,598 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief 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. + * + * Assuming N quantization steps, the scaling factor becomes s=2*PI*(N-1); + * we should probably have about 1 scaling factor for every 1/4 + * quantization step (perhaps 1/8 for low levels of quantization) + */ +/*----------------------------------------------------------------------------*/ + +#include +#include "astc_codec_internals.h" + +#ifdef DEBUG_PRINT_DIAGNOSTICS + #include +#endif + +static const float angular_steppings[] = { + 1.0, 1.125, + 1.25, 1.375, + 1.5, 1.625, + 1.75, 1.875, + + 2.0, 2.25, 2.5, 2.75, + 3.0, 3.25, 3.5, 3.75, + 4.0, 4.25, 4.5, 4.75, + 5.0, 5.25, 5.5, 5.75, + 6.0, 6.25, 6.5, 6.75, + 7.0, 7.25, 7.5, 7.75, + + 8.0, 8.5, + 9.0, 9.5, + 10.0, 10.5, + 11.0, 11.5, + 12.0, 12.5, + 13.0, 13.5, + 14.0, 14.5, + 15.0, 15.5, + 16.0, 16.5, + 17.0, 17.5, + 18.0, 18.5, + 19.0, 19.5, + 20.0, 20.5, + 21.0, 21.5, + 22.0, 22.5, + 23.0, 23.5, + 24.0, 24.5, + 25.0, 25.5, + 26.0, 26.5, + 27.0, 27.5, + 28.0, 28.5, + 29.0, 29.5, + 30.0, 30.5, + 31.0, 31.5, + 32.0, 32.5, + 33.0, 33.5, + 34.0, 34.5, + 35.0, 35.5, +}; + +#define ANGULAR_STEPS ((int)(sizeof(angular_steppings)/sizeof(angular_steppings[0]))) + +static float stepsizes[ANGULAR_STEPS]; +static float stepsizes_sqr[ANGULAR_STEPS]; + +static int max_angular_steps_needed_for_quant_level[13]; + +// we store sine/cosine values for 64 possible weight values; this causes +// slight quality loss compared to using sin() and cos() directly. + +#define SINCOS_STEPS 64 + +static float sin_table[SINCOS_STEPS][ANGULAR_STEPS]; +static float cos_table[SINCOS_STEPS][ANGULAR_STEPS]; + +void prepare_angular_tables(void) +{ + int i, j; + int max_angular_steps_needed_for_quant_steps[40]; + for (i = 0; i < ANGULAR_STEPS; i++) + { + stepsizes[i] = 1.0f / angular_steppings[i]; + stepsizes_sqr[i] = stepsizes[i] * stepsizes[i]; + + for (j = 0; j < SINCOS_STEPS; j++) + { + sin_table[j][i] = static_cast < float >(sin((2.0f * M_PI / (SINCOS_STEPS - 1.0f)) * angular_steppings[i] * j)); + cos_table[j][i] = static_cast < float >(cos((2.0f * M_PI / (SINCOS_STEPS - 1.0f)) * angular_steppings[i] * j)); + } + + int p = static_cast < int >(floor(angular_steppings[i])) + 1; + max_angular_steps_needed_for_quant_steps[p] = MIN(i + 1, ANGULAR_STEPS - 1); + } + + + // yes, the next-to-last entry is supposed to have the value 33. This because under + // ASTC, the 32-weight mode leaves a double-sized hole in the middle of the + // weight space, so we are better off matching 33 weights than 32. + static const int steps_of_level[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 33, 36 }; + + for (i = 0; i < 13; i++) + max_angular_steps_needed_for_quant_level[i] = max_angular_steps_needed_for_quant_steps[steps_of_level[i]]; + +} + + +union if32 +{ + float f; + int32_t s; + uint32_t u; +}; + + +// function to compute angular sums; then, from the +// angular sums, compute alignment factor and offset. + +/* static inline */ +void compute_angular_offsets(int samplecount, const float *samples, const float *sample_weights, int max_angular_steps, float *offsets) +{ + int i, j; + + float anglesum_x[ANGULAR_STEPS]; + float anglesum_y[ANGULAR_STEPS]; + + for (i = 0; i < max_angular_steps; i++) + { + anglesum_x[i] = 0; + anglesum_y[i] = 0; + } + + + // compute the angle-sums. + for (i = 0; i < samplecount; i++) + { + float sample = samples[i]; + float sample_weight = sample_weights[i]; + if32 p; + p.f = (sample * (SINCOS_STEPS - 1.0f)) + 12582912.0f; + unsigned int isample = p.u & 0x3F; + + const float *sinptr = sin_table[isample]; + const float *cosptr = cos_table[isample]; + + for (j = 0; j < max_angular_steps; j++) + { + float cp = cosptr[j]; + float sp = sinptr[j]; + + anglesum_x[j] += cp * sample_weight; + anglesum_y[j] += sp * sample_weight; + } + } + + // post-process the angle-sums + for (i = 0; i < max_angular_steps; i++) + { + float angle = atan2(anglesum_y[i], anglesum_x[i]); // positive angle -> positive offset + offsets[i] = angle * (stepsizes[i] * (1.0f / (2.0f * (float)M_PI))); + } +} + + + +// for a given step-size and a given offset, compute the +// lowest and highest weight that results from quantizing using the stepsize & offset. +// also, compute the resulting error. + + +/* static inline */ +void compute_lowest_and_highest_weight(int samplecount, const float *samples, const float *sample_weights, + int max_angular_steps, const float *offsets, + int8_t * lowest_weight, int8_t * highest_weight, + float *error, float *cut_low_weight_error, float *cut_high_weight_error) +{ + int i; + + int sp; + + float error_from_forcing_weight_down[60]; + float error_from_forcing_weight_either_way[60]; + for (i = 0; i < 60; i++) + { + error_from_forcing_weight_down[i] = 0; + error_from_forcing_weight_either_way[i] = 0; + } + + // weight + 12 + static const unsigned int idxtab[256] = { + + 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, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 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, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 5, 6, 7, 8, 9, 10, 11 + }; + + + + for (sp = 0; sp < max_angular_steps; sp++) + { + unsigned int minidx_bias12 = 55; + unsigned int maxidx_bias12 = 0; + + float errval = 0.0f; + + float rcp_stepsize = angular_steppings[sp]; + float offset = offsets[sp]; + + float scaled_offset = rcp_stepsize * offset; + + + for (i = 0; i < samplecount - 1; i += 2) + { + float wt1 = sample_weights[i]; + float wt2 = sample_weights[i + 1]; + if32 p1, p2; + float sval1 = (samples[i] * rcp_stepsize) - scaled_offset; + float sval2 = (samples[i + 1] * rcp_stepsize) - scaled_offset; + p1.f = sval1 + 12582912.0f; // FP representation abuse to avoid floor() and float->int conversion + p2.f = sval2 + 12582912.0f; // FP representation abuse to avoid floor() and float->int conversion + float isval1 = p1.f - 12582912.0f; + float isval2 = p2.f - 12582912.0f; + float dif1 = sval1 - isval1; + float dif2 = sval2 - isval2; + + errval += (dif1 * wt1) * dif1; + errval += (dif2 * wt2) * dif2; + + // table lookups that really perform a minmax function. + unsigned int idx1_bias12 = idxtab[p1.u & 0xFF]; + unsigned int idx2_bias12 = idxtab[p2.u & 0xFF]; + + if (idx1_bias12 < minidx_bias12) + minidx_bias12 = idx1_bias12; + if (idx1_bias12 > maxidx_bias12) + maxidx_bias12 = idx1_bias12; + if (idx2_bias12 < minidx_bias12) + minidx_bias12 = idx2_bias12; + if (idx2_bias12 > maxidx_bias12) + maxidx_bias12 = idx2_bias12; + + error_from_forcing_weight_either_way[idx1_bias12] += wt1; + error_from_forcing_weight_down[idx1_bias12] += (dif1 * wt1); + + error_from_forcing_weight_either_way[idx2_bias12] += wt2; + error_from_forcing_weight_down[idx2_bias12] += (dif2 * wt2); + } + + if (samplecount & 1) + { + i = samplecount - 1; + float wt = sample_weights[i]; + if32 p; + float sval = (samples[i] * rcp_stepsize) - scaled_offset; + p.f = sval + 12582912.0f; // FP representation abuse to avoid floor() and float->int conversion + float isval = p.f - 12582912.0f; + float dif = sval - isval; + + errval += (dif * wt) * dif; + + unsigned int idx_bias12 = idxtab[p.u & 0xFF]; + + if (idx_bias12 < minidx_bias12) + minidx_bias12 = idx_bias12; + if (idx_bias12 > maxidx_bias12) + maxidx_bias12 = idx_bias12; + + error_from_forcing_weight_either_way[idx_bias12] += wt; + error_from_forcing_weight_down[idx_bias12] += dif * wt; + } + + + lowest_weight[sp] = (int)minidx_bias12 - 12; + highest_weight[sp] = (int)maxidx_bias12 - 12; + error[sp] = errval; + + // the cut_(lowest/highest)_weight_error indicate the error that results from + // forcing samples that should have had the (lowest/highest) weight value + // one step (up/down). + cut_low_weight_error[sp] = error_from_forcing_weight_either_way[minidx_bias12] - 2.0f * error_from_forcing_weight_down[minidx_bias12]; + cut_high_weight_error[sp] = error_from_forcing_weight_either_way[maxidx_bias12] + 2.0f * error_from_forcing_weight_down[maxidx_bias12]; + + // clear out the error-from-forcing values we actually used in this pass + // so that these are clean for the next pass. + unsigned int ui; + for (ui = minidx_bias12 & ~0x3; ui <= maxidx_bias12; ui += 4) + { + error_from_forcing_weight_either_way[ui] = 0; + error_from_forcing_weight_down[ui] = 0; + error_from_forcing_weight_either_way[ui + 1] = 0; + error_from_forcing_weight_down[ui + 1] = 0; + error_from_forcing_weight_either_way[ui + 2] = 0; + error_from_forcing_weight_down[ui + 2] = 0; + error_from_forcing_weight_either_way[ui + 3] = 0; + error_from_forcing_weight_down[ui + 3] = 0; + } + } + + + for (sp = 0; sp < max_angular_steps; sp++) + { + float errscale = stepsizes_sqr[sp]; + error[sp] *= errscale; + cut_low_weight_error[sp] *= errscale; + cut_high_weight_error[sp] *= errscale; + } +} + + + +// main function for running the angular algorithm. + + +void compute_angular_endpoints_for_quantization_levels(int samplecount, const float *samples, const float *sample_weights, int max_quantization_level, float low_value[12], float high_value[12]) +{ + int i; + + + max_quantization_level++; // Temporarily increase level - needs refinement + + static const int quantization_steps_for_level[13] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 33, 36 }; + int max_quantization_steps = quantization_steps_for_level[max_quantization_level]; + + float offsets[ANGULAR_STEPS]; + + int max_angular_steps = max_angular_steps_needed_for_quant_level[max_quantization_level]; + + compute_angular_offsets(samplecount, samples, sample_weights, max_angular_steps, offsets); + + + // the +4 offsets are to allow for vectorization within compute_lowest_and_highest_weight(). + int8_t lowest_weight[ANGULAR_STEPS + 4]; + int8_t highest_weight[ANGULAR_STEPS + 4]; + float error[ANGULAR_STEPS + 4]; + + float cut_low_weight_error[ANGULAR_STEPS + 4]; + float cut_high_weight_error[ANGULAR_STEPS + 4]; + + compute_lowest_and_highest_weight(samplecount, samples, sample_weights, max_angular_steps, offsets, lowest_weight, highest_weight, error, cut_low_weight_error, cut_high_weight_error); + + + #ifdef DEBUG_PRINT_DIAGNOSTICS + if (print_diagnostics) + { + printf("%s : max-angular-steps=%d \n", __func__, max_angular_steps); + printf("Samplecount=%d, max_quantization_level=%d\n", samplecount, max_quantization_level); + for (i = 0; i < samplecount; i++) + printf("Sample %d : %f (weight %f)\n", i, samples[i], sample_weights[i]); + + for (i = 0; i < max_angular_steps; i++) + { + printf("%d: offset=%f error=%f lowest=%d highest=%d cl=%f ch=%f\n", i, offsets[i], error[i], lowest_weight[i], highest_weight[i], cut_low_weight_error[i], cut_high_weight_error[i]); + } + printf("\n"); + } + #endif + + // for each quantization level, find the best error terms. + float best_errors[40]; + int best_scale[40]; + uint8_t cut_low_weight[40]; + + for (i = 0; i < (max_quantization_steps + 4); i++) + { + best_errors[i] = 1e30f; + best_scale[i] = -1; // Indicates no solution found + cut_low_weight[i] = 0; + } + + + + for (i = 0; i < max_angular_steps; i++) + { + int samplecount = highest_weight[i] - lowest_weight[i] + 1; + if (samplecount >= (max_quantization_steps + 4)) + { + continue; + } + if (samplecount < 2) + samplecount = 2; + + if (best_errors[samplecount] > error[i]) + { + best_errors[samplecount] = error[i]; + best_scale[samplecount] = i; + cut_low_weight[samplecount] = 0; + } + + 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]; + + if (best_errors[samplecount - 1] > error_cut_low) + { + best_errors[samplecount - 1] = error_cut_low; + best_scale[samplecount - 1] = i; + cut_low_weight[samplecount - 1] = 1; + } + + if (best_errors[samplecount - 1] > error_cut_high) + { + best_errors[samplecount - 1] = error_cut_high; + best_scale[samplecount - 1] = i; + cut_low_weight[samplecount - 1] = 0; + } + + if (best_errors[samplecount - 2] > error_cut_low_high) + { + best_errors[samplecount - 2] = error_cut_low_high; + best_scale[samplecount - 2] = i; + cut_low_weight[samplecount - 2] = 1; + } + + } + + // if we got a better error-value for a low sample count than for a high one, + // use the low sample count error value for the higher sample count as well. + for (i = 3; i <= max_quantization_steps; i++) + { + if (best_errors[i] > best_errors[i - 1]) + { + best_errors[i] = best_errors[i - 1]; + best_scale[i] = best_scale[i - 1]; + cut_low_weight[i] = cut_low_weight[i - 1]; + } + } + + + max_quantization_level--; // Decrease level again (see corresponding ++, above) + + static const int ql_weights[12] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 33 }; + for (i = 0; i <= max_quantization_level; i++) + { + int q = ql_weights[i]; + int bsi = best_scale[q]; + + // Did we find anything? + if(bsi < 0) + { + printf("ERROR: Unable to find an encoding within the specified error limits. Please revise the error limit values and try again.\n"); + exit(1); + } + + float stepsize = stepsizes[bsi]; + int lwi = lowest_weight[bsi] + cut_low_weight[q]; + int hwi = lwi + q - 1; + float offset = offsets[bsi]; + + low_value[i] = offset + lwi * stepsize; + high_value[i] = offset + hwi * stepsize; + } + +} + + +// helper functions that will compute ideal angular-endpoints +// for a given set of weights and a given block size descriptors + +void compute_angular_endpoints_1plane(float mode_cutoff, const block_size_descriptor * bsd, + const float *decimated_quantized_weights, const float *decimated_weights, + float low_value[MAX_WEIGHT_MODES], float high_value[MAX_WEIGHT_MODES]) +{ + int i; + float low_values[MAX_DECIMATION_MODES][12]; + float high_values[MAX_DECIMATION_MODES][12]; + + for (i = 0; i < MAX_DECIMATION_MODES; i++) + { + int samplecount = bsd->decimation_mode_samples[i]; + int quant_mode = bsd->decimation_mode_maxprec_1plane[i]; + float percentile = bsd->decimation_mode_percentile[i]; + int permit_encode = bsd->permit_encode[i]; + if (permit_encode == 0 || samplecount < 1 || quant_mode < 0 || percentile > mode_cutoff) + continue; + + + compute_angular_endpoints_for_quantization_levels(samplecount, + decimated_quantized_weights + i * MAX_WEIGHTS_PER_BLOCK, + decimated_weights + i * MAX_WEIGHTS_PER_BLOCK, quant_mode, low_values[i], high_values[i]); + } + + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (bsd->block_modes[i].is_dual_plane != 0 || bsd->block_modes[i].percentile > mode_cutoff) + continue; + int quant_mode = bsd->block_modes[i].quantization_mode; + int decim_mode = bsd->block_modes[i].decimation_mode; + + low_value[i] = low_values[decim_mode][quant_mode]; + high_value[i] = high_values[decim_mode][quant_mode]; + } + +} + + + +void compute_angular_endpoints_2planes(float mode_cutoff, + const block_size_descriptor * bsd, + const float *decimated_quantized_weights, + const float *decimated_weights, + float low_value1[MAX_WEIGHT_MODES], float high_value1[MAX_WEIGHT_MODES], float low_value2[MAX_WEIGHT_MODES], float high_value2[MAX_WEIGHT_MODES]) +{ + int i; + float low_values1[MAX_DECIMATION_MODES][12]; + float high_values1[MAX_DECIMATION_MODES][12]; + float low_values2[MAX_DECIMATION_MODES][12]; + float high_values2[MAX_DECIMATION_MODES][12]; + + for (i = 0; i < MAX_DECIMATION_MODES; i++) + { + int samplecount = bsd->decimation_mode_samples[i]; + int quant_mode = bsd->decimation_mode_maxprec_2planes[i]; + float percentile = bsd->decimation_mode_percentile[i]; + int permit_encode = bsd->permit_encode[i]; + if (permit_encode == 0 || samplecount < 1 || quant_mode < 0 || percentile > mode_cutoff) + continue; + + compute_angular_endpoints_for_quantization_levels(samplecount, + decimated_quantized_weights + 2 * i * MAX_WEIGHTS_PER_BLOCK, + decimated_weights + 2 * i * MAX_WEIGHTS_PER_BLOCK, quant_mode, low_values1[i], high_values1[i]); + + compute_angular_endpoints_for_quantization_levels(samplecount, + decimated_quantized_weights + (2 * i + 1) * MAX_WEIGHTS_PER_BLOCK, + decimated_weights + (2 * i + 1) * MAX_WEIGHTS_PER_BLOCK, quant_mode, low_values2[i], high_values2[i]); + + } + + for (i = 0; i < MAX_WEIGHT_MODES; i++) + { + if (bsd->block_modes[i].is_dual_plane != 1 || bsd->block_modes[i].percentile > mode_cutoff) + continue; + int quant_mode = bsd->block_modes[i].quantization_mode; + int decim_mode = bsd->block_modes[i].decimation_mode; + + 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]; + } +} diff --git a/third_party/astcenc/Source/astc_weight_quant_xfer_tables.cpp b/third_party/astcenc/Source/astc_weight_quant_xfer_tables.cpp new file mode 100644 index 0000000000..4294735021 --- /dev/null +++ b/third_party/astcenc/Source/astc_weight_quant_xfer_tables.cpp @@ -0,0 +1,1003 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Quantization transfer tables for ASTC. + */ +/*----------------------------------------------------------------------------*/ + + +#include "astc_codec_internals.h" + +const quantization_and_transfer_table quant_and_xfer_tables[12] = { + // quantization method 0, range 0..1 + { + QUANT_2, + {0, 64,}, + { + 0.000000, 1.000000,}, + {0, 0,}, + {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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, + }, + }, + + + + + // quantization method 1, range 0..2 + { + QUANT_3, + {0, 32, 64,}, + { + 0.000000, 0.500000, 1.000000,}, + {0, 0, 1,}, + {1, 2, 2,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, + }, + }, + + + + + // quantization method 2, range 0..3 + { + QUANT_4, + {0, 21, 43, 64,}, + { + 0.000000, 0.328125, 0.671875, 1.000000,}, + {0, 0, 1, 2,}, + {1, 2, 3, 3,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, + }, + }, + + + + + // quantization method 3, range 0..4 + { + QUANT_5, + {0, 16, 32, 48, 64,}, + { + 0.000000, 0.250000, 0.500000, 0.750000, + 1.000000,}, + {0, 0, 1, 2, 3,}, + {1, 2, 3, 4, 4,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, + }, + }, + + + + + // quantization method 4, range 0..5 + { + QUANT_6, + {0, 64, 12, 52, 25, 39,}, + { + 0.000000, 1.000000, 0.187500, 0.812500, + 0.390625, 0.609375,}, + {0, 3, 0, 5, 2, 4,}, + {2, 1, 4, 1, 5, 3,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 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, 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, 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, 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, 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, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, + }, + }, + + + + + // quantization method 5, range 0..7 + { + QUANT_8, + {0, 9, 18, 27, 37, 46, 55, 64,}, + { + 0.000000, 0.140625, 0.281250, 0.421875, + 0.578125, 0.718750, 0.859375, 1.000000,}, + {0, 0, 1, 2, 3, 4, 5, 6,}, + {1, 2, 3, 4, 5, 6, 7, 7,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 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, 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, 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, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 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, 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, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 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, 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, + 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, 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, 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, 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, + }, + }, + + + + + // quantization method 6, range 0..9 + { + QUANT_10, + {0, 64, 7, 57, 14, 50, 21, 43, 28, 36,}, + { + 0.000000, 1.000000, 0.109375, 0.890625, + 0.218750, 0.781250, 0.328125, 0.671875, + 0.437500, 0.562500,}, + {0, 3, 0, 5, 2, 7, 4, 9, 6, 8,}, + {2, 1, 4, 1, 6, 3, 8, 5, 9, 7,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 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, 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, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 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, 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, 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, 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, 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, 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, + 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, 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, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 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, 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, 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, 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, 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, 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, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, + }, + }, + + + + + // quantization method 7, range 0..11 + { + QUANT_12, + {0, 64, 17, 47, 5, 59, 23, 41, 11, 53, 28, 36,}, + { + 0.000000, 1.000000, 0.265625, 0.734375, + 0.078125, 0.921875, 0.359375, 0.640625, + 0.171875, 0.828125, 0.437500, 0.562500,}, + {0, 5, 8, 7, 0, 9, 2, 11, 4, 3, 6, 10,}, + {4, 1, 6, 9, 8, 1, 10, 3, 2, 5, 11, 7,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 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, 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, 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, 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, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 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, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, + }, + }, + + + + + // quantization method 8, range 0..15 + { + QUANT_16, + {0, 4, 8, 12, 17, 21, 25, 29, 35, 39, 43, 47, 52, 56, 60, 64,}, + { + 0.000000, 0.062500, 0.125000, 0.187500, + 0.265625, 0.328125, 0.390625, 0.453125, + 0.546875, 0.609375, 0.671875, 0.734375, + 0.812500, 0.875000, 0.937500, 1.000000,}, + {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 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, 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, 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, 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, + 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, 7, 7, 7, 7, + 7, 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, 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, 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, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 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, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 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, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 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, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, + }, + }, + + + + + // quantization method 9, range 0..19 + { + QUANT_20, + {0, 64, 16, 48, 3, 61, 19, 45, 6, 58, 23, 41, 9, 55, 26, 38, 13, 51, 29, 35,}, + { + 0.000000, 1.000000, 0.250000, 0.750000, + 0.046875, 0.953125, 0.296875, 0.703125, + 0.093750, 0.906250, 0.359375, 0.640625, + 0.140625, 0.859375, 0.406250, 0.593750, + 0.203125, 0.796875, 0.453125, 0.546875,}, + {0, 5, 16, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 17, 10, 19, 12, 3, 14, 18,}, + {4, 1, 6, 17, 8, 1, 10, 3, 12, 5, 14, 7, 16, 9, 18, 11, 2, 13, 19, 15,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 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, 8, 8, 8, 8, 8, 8, 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, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 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, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 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, 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, 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, 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, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 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, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 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, 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, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 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, 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, + 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, 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, 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, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 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, + 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, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, + }, + }, + + + + + // quantization method 10, range 0..23 + { + QUANT_24, + {0, 64, 8, 56, 16, 48, 24, 40, 2, 62, 11, 53, 19, 45, 27, 37, 5, 59, 13, 51, 22, 42, 30, 34,}, + { + 0.000000, 1.000000, 0.125000, 0.875000, + 0.250000, 0.750000, 0.375000, 0.625000, + 0.031250, 0.968750, 0.171875, 0.828125, + 0.296875, 0.703125, 0.421875, 0.578125, + 0.078125, 0.921875, 0.203125, 0.796875, + 0.343750, 0.656250, 0.468750, 0.531250,}, + {0, 9, 16, 11, 18, 13, 20, 15, 0, 17, 2, 19, 4, 21, 6, 23, 8, 3, 10, 5, 12, 7, 14, 22,}, + {8, 1, 10, 17, 12, 19, 14, 21, 16, 1, 18, 3, 20, 5, 22, 7, 2, 9, 4, 11, 6, 13, 23, 15,}, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 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, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 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, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 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, 6, 6, 6, 6, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 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, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 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, 21, 21, 21, 21, 21, 21, 21, 21, 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, 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, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 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, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, + }, + }, + + + + + // quantization method 11, range 0..31 + { + QUANT_32, + {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.000000, 0.031250, 0.062500, 0.093750, + 0.125000, 0.156250, 0.187500, 0.218750, + 0.250000, 0.281250, 0.312500, 0.343750, + 0.375000, 0.406250, 0.437500, 0.468750, + 0.531250, 0.562500, 0.593750, 0.625000, + 0.656250, 0.687500, 0.718750, 0.750000, + 0.781250, 0.812500, 0.843750, 0.875000, + 0.906250, 0.937500, 0.968750, 1.000000,}, + {0, 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,}, + {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, 31,}, + { + 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, 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, 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, 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, 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, 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, 9, 9, + 9, 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, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 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, 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, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 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, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 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, 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, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 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, 26, 26, 26, + 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 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, 28, 28, 28, + 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 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, 30, + 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, + }, + }, + +}; diff --git a/third_party/astcenc/Source/exr_to_htga.cpp b/third_party/astcenc/Source/exr_to_htga.cpp new file mode 100644 index 0000000000..2fd0b5b335 --- /dev/null +++ b/third_party/astcenc/Source/exr_to_htga.cpp @@ -0,0 +1,212 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Program to convert FP16 images between EXR and HTGA (half-float TGA) + * + * This program uses TGA imagetypes 130/131 (non-standard); + * the data are stored as FP16 B,G,R,A (B in first two bytes, then G + * in next two, then R in the next two, then alpha in the final two + * bytes. + */ +/*----------------------------------------------------------------------------*/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + +using namespace std; +using namespace Imf; +using namespace Imath; + +struct tga_header +{ + uint8_t identsize; + uint8_t colormaptype; + uint8_t imagetype; + uint8_t dummied[5]; + uint16_t xstart; + uint16_t ystart; + uint16_t xsize; + uint16_t ysize; + uint8_t bitsperpixel; + uint8_t descriptor; +}; + + +void convert_exr_to_htga(const char *exr_filename, const char *htga_filename) +{ + tga_header hdr = { 0, 0, 128 + 2, {0, 0, 0, 0, 0}, 0, 0, 0, 0, 64, 0x00 }; + + RgbaInputFile file(exr_filename); + Box2i dw = file.dataWindow(); + + int width = dw.max.x - dw.min.x + 1; + int height = dw.max.y - dw.min.y + 1; + Array2D < Rgba > pixels(height, width); + + pixels.resizeErase(height, width); + + file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width, 1, width); + file.readPixels(dw.min.y, dw.max.y); + + + uint16_t *buffer = (uint16_t *) malloc(width * height * 8); + + uint16_t *b2 = buffer; + + int x, y; + for (y = 0; y < height; y++) + { + int y_src = y; + // int y_src = height - y - 1; + for (x = 0; x < width; x++) + { + *b2++ = pixels[y_src][x].b.bits(); + *b2++ = pixels[y_src][x].g.bits(); + *b2++ = pixels[y_src][x].r.bits(); + *b2++ = pixels[y_src][x].a.bits(); + } + } + + hdr.xsize = width; + hdr.ysize = height; + + FILE *f = fopen(htga_filename, "wb"); + fwrite(&hdr, 1, 18, f); + fwrite(buffer, 1, 8 * width * height, f); + fclose(f); + + return; +} + +int convert_htga_to_exr(const char *htga_filename, const char *exr_filename) +{ + int i; + tga_header hdr; + + FILE *f = fopen(htga_filename, "rb"); + if (!f) + return -1; + + int bytes_read; + bytes_read = fread(&hdr, 1, 18, f); + if (bytes_read < 18) + { + fclose(f); + return -1; + } + + int width = hdr.xsize; + int height = hdr.ysize; + int bitsperpixel = hdr.bitsperpixel; + + fseek(f, hdr.identsize, SEEK_CUR); + + uint16_t *buf = new uint16_t[width * height * (bitsperpixel / 16)]; + int bytestoread = width * height * (bitsperpixel / 16) * 2; + bytes_read = fread(buf, 1, bytestoread, f); + fclose(f); + if (bytes_read != bytestoread) + { + delete[]buf; + return -1; + } + + int pixelcount = width * height; + Rgba *pixels = new Rgba[pixelcount]; + + int wordsperpixel = bitsperpixel / 16; + + int y; + for (y = 0; y < height; y++) + { + uint16_t *src = buf + (width * y * wordsperpixel); + + int dst = width * y; + switch (hdr.bitsperpixel) + { + case 16: // Luminance + for (i = 0; i < width; i++) + { + pixels[i + dst].r.setBits(src[0]); + pixels[i + dst].g.setBits(src[0]); + pixels[i + dst].b.setBits(src[0]); + pixels[i + dst].a.setBits(0x3C00); + src++; + } + break; + case 32: // Luminance-Alpha + for (i = 0; i < width; i++) + { + pixels[i + dst].r.setBits(src[0]); + pixels[i + dst].g.setBits(src[0]); + pixels[i + dst].b.setBits(src[0]); + pixels[i + dst].a.setBits(src[1]); + src += 2; + } + break; + case 48: // RGB + for (i = 0; i < width; i++) + { + pixels[i + dst].r.setBits(src[2]); + pixels[i + dst].g.setBits(src[1]); + pixels[i + dst].b.setBits(src[0]); + pixels[i + dst].a.setBits(0x3C00); + src += 3; + } + break; + case 64: + for (i = 0; i < width; i++) + { + pixels[i + dst].r.setBits(src[2]); + pixels[i + dst].g.setBits(src[1]); + pixels[i + dst].b.setBits(src[0]); + pixels[i + dst].a.setBits(src[3]); + src += 4; + } + } + } + RgbaOutputFile file(exr_filename, width, height, WRITE_RGBA); + file.setFrameBuffer(pixels, 1, width); + file.writePixels(height); + delete[]buf; + delete[]pixels; + return 0; +} + +int main(int argc, char **argv) +{ + + if (argc < 4) + { + printf("EXR <-> HTGA (half-float-TGA) conversion tool\n" + "Usage:\n" " %s \n" "where operation may be\n" " -q : convert from EXR to HTGA\n" " -e : convert from HTGA to EXR\n", argv[0]); + return 1; + } + + if (!strcmp(argv[1], "-q")) + convert_exr_to_htga(argv[2], argv[3]); + else if (!strcmp(argv[1], "-e")) + convert_htga_to_exr(argv[2], argv[3]); + + + return 0; + +} diff --git a/third_party/astcenc/Source/mathlib.cpp b/third_party/astcenc/Source/mathlib.cpp new file mode 100644 index 0000000000..3c41a0af01 --- /dev/null +++ b/third_party/astcenc/Source/mathlib.cpp @@ -0,0 +1,772 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Library of math functions. + */ +/*----------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include "mathlib.h" + +/************************** + basic OpenCL functions +**************************/ + +float inversesqrt(float p) +{ + return 1.0f / sqrt(p); +} +float acospi(float p) +{ + return static_cast < float >(acos(p) * (1.0f / M_PI)); +}; +float sinpi(float p) +{ + return static_cast < float >(sin(p * M_PI)); +} +float cospi(float p) +{ + return static_cast < float >(cos(p * M_PI)); +} + + +float nan(int p) +{ + union + { + int p; + float q; + } v; + v.p = p | 0x7FC00000U; + return v.q; +} + +#if (!_MSC_VER) && (__cplusplus < 201103L) +float fmax(float p, float q) +{ + if (p != p) + return q; + if (q != q) + return p; + if (p > q) + return p; + return q; +} + +float fmin(float p, float q) +{ + if (p != p) + return q; + if (q != q) + return p; + if (p < q) + return p; + return q; +} +#endif // C++11 + +float2 fmax(float2 p, float2 q) +{ + return float2(fmax(p.x, q.x), fmax(p.y, q.y)); +} + +float3 fmax(float3 p, float3 q) +{ + return float3(fmax(p.x, q.x), fmax(p.y, q.y), fmax(p.z, q.z)); +} + +float4 fmax(float4 p, float4 q) +{ + return float4(fmax(p.x, q.x), fmax(p.y, q.y), fmax(p.z, q.z), fmax(p.w, q.w)); +} + + +float2 fmin(float2 p, float2 q) +{ + return float2(fmin(p.x, q.x), fmin(p.y, q.y)); +} + +float3 fmin(float3 p, float3 q) +{ + return float3(fmin(p.x, q.x), fmin(p.y, q.y), fmin(p.z, q.z)); +} + +float4 fmin(float4 p, float4 q) +{ + return float4(fmin(p.x, q.x), fmin(p.y, q.y), fmin(p.z, q.z), fmin(p.w, q.w)); +} + +/* + float dot( float2 p, float2 q ) { return p.x*q.x + p.y*q.y; } float dot( float3 p, float3 q ) { return p.x*q.x + p.y*q.y + p.z*q.z; } float dot( float4 p, float4 q ) { return p.x*q.x + p.y*q.y + + p.z*q.z + p.w*q.w; } */ + +float3 cross(float3 p, float3 q) +{ + return p.yzx * q.zxy - p.zxy * q.yzx; +} + +float4 cross(float4 p, float4 q) +{ + return float4(p.yzx * q.zxy - p.zxy * q.yzx, 0.0f); +} + +float length(float2 p) +{ + return sqrt(dot(p, p)); +} + +float length(float3 p) +{ + return sqrt(dot(p, p)); +} + +float length(float4 p) +{ + return sqrt(dot(p, p)); +} + +float length_sqr(float2 p) +{ + return dot(p, p); +} + +float length_sqr(float3 p) +{ + return dot(p, p); +} + +float length_sqr(float4 p) +{ + return dot(p, p); +} + + +float distance(float2 p, float2 q) +{ + return length(q - p); +} + +float distance(float3 p, float3 q) +{ + return length(q - p); +} + +float distance(float4 p, float4 q) +{ + return length(q - p); +} + +float distance_sqr(float2 p, float2 q) +{ + return length_sqr(q - p); +} + +float distance_sqr(float3 p, float3 q) +{ + return length_sqr(q - p); +} + +float distance_sqr(float4 p, float4 q) +{ + return length_sqr(q - p); +} + + +float2 normalize(float2 p) +{ + return p / length(p); +} + +float3 normalize(float3 p) +{ + return p / length(p); +} + +float4 normalize(float4 p) +{ + return p / length(p); +} + + +/************************************************** + matrix functions, for 2x2, 3x3 and 4x4 matrices: + + * trace + * determinant + * transform + * inverse + * adjugate + * characteristic polynomial + * eigenvalue + * eigenvector + + additionally, root solver + for 2nd, 3rd and 4th degree monic polynomials. + +*************************************************/ + +/* + struct mat2 { float2 v[2]; }; + struct mat3 { float3 v[3]; }; + struct mat4 { float4 v[4]; }; +*/ + +float trace(mat2 p) +{ + return p.v[0].x + p.v[1].y; +} + +float trace(mat3 p) +{ + return p.v[0].x + p.v[1].y + p.v[2].z; +} + +float trace(mat4 p) +{ + return p.v[0].x + p.v[1].y + p.v[2].z + p.v[3].w; +} + +float determinant(mat2 p) +{ + float2 v = p.v[0].xy * p.v[1].yx; + return v.x - v.y; +} + +float determinant(mat3 p) +{ + return dot(p.v[0], cross(p.v[1], p.v[2])); +} + +float determinant(mat4 p) +{ + return dot(p.v[0], + float4(dot(p.v[1].yzw, cross(p.v[2].yzw, p.v[3].yzw)), + -dot(p.v[1].xzw, cross(p.v[2].xzw, p.v[3].xzw)), dot(p.v[1].xyw, cross(p.v[2].xyw, p.v[3].xyw)), -dot(p.v[1].xyz, cross(p.v[2].xyz, p.v[3].xyz)))); +} + + +/* + characteristic polynomials for matrices. These polynomials are monic, meaning that the coefficient of the highest component is 1; this component is omitted. The first component is the constant + part. */ + +float2 characteristic_poly(mat2 p) +{ + return float2(determinant(p), -trace(p)); +} + + +float3 characteristic_poly(mat3 p) +{ + float2 v1 = (p.v[0].xy * p.v[1].yx) + (p.v[0].xz * p.v[2].zx) + (p.v[1].yz * p.v[2].zy); + + return float3(-determinant(p), v1.x - v1.y, -trace(p)); +} + + +float4 characteristic_poly(mat4 p) +{ + float2 v1 = (p.v[0].xy * p.v[1].yx) + (p.v[0].xz * p.v[2].zx) + (p.v[0].xw * p.v[3].wx) + (p.v[1].yz * p.v[2].zy) + (p.v[1].yw * p.v[3].wy) + (p.v[2].zw * p.v[3].wz); + + return float4(determinant(p), + -dot(p.v[1].yzw, cross(p.v[2].yzw, p.v[3].yzw)) + - dot(p.v[0].xzw, cross(p.v[2].xzw, p.v[3].xzw)) - dot(p.v[0].xyw, cross(p.v[1].xyw, p.v[3].xyw)) - dot(p.v[0].xyz, cross(p.v[1].xyz, p.v[2].xyz)), v1.x - v1.y, -trace(p)); +} + + +/* + Root finders for monic polynomials (highest coefficient is equal to 1) + + Returns a vector with length equal to the number of roots that the polynomial has; + for roots that do not genuinely exist, we return NaN. + + The polynomial is basically + + poly(n) = p.x + p.y*n + p.z*n^2 + p.w*n^3 + + (including only the components of the vector that actually exist; the next coefficient + has the value 1, and the remaining ones have value 0. ) + */ + + +float2 solve_monic(float2 p) +{ + float v = sqrt(p.y * p.y - 4 * p.x); + return (p.yy + float2(v, -v)) * -0.5f; +} + +float3 solve_monic(float3 p) +{ + + p = p * (1.0f / 3.0f); + + float pz = p.z; + + // compute a normalization value to scale the vector by. + // The normalization factor is divided by 2^20. + // This is supposed to make internal calculations unlikely + // to overflow while also making underflows unlikely. + float scal = 1.0f; + + float cx = static_cast < float >(cbrt(fabs(p.x))); + float cy = static_cast < float >(cbrt(fabs(p.y))); + scal = fmax(fmax(fabsf(p.z), cx), cy * cy) * (1.0f / 1048576.0f); + float rscal = 1.0f / scal; + p = p * float3(rscal * rscal * rscal, rscal * rscal, rscal); + + float bb = p.z * p.z; // div scal^2 + + float nq = bb - p.y; // div scal^2 + float r = 1.5f * (p.y * p.z - p.x) - p.z * bb; // div scal^3 + float nq3 = nq * nq * nq; // div scal^6 + float r2 = r * r; // div scal^6 + + if (nq3 < r2) + { + // one root + float root = sqrt(r2 - nq3); // div scal^3 + float s = static_cast < float >(cbrt(r + root)); // div scal + float t = static_cast < float >(cbrt(r - root)); // div scal + return float3((s + t) * scal - pz, nan(0), nan(0)); + } + else + { + // three roots + float phi_r = inversesqrt(nq3); // div scal ^ -3 + float phi_root = static_cast < float >(cbrt(phi_r * nq3)); // div scal + float theta = acospi(r * phi_r); + theta *= 1.0f / 3.0f; + float ncprod = phi_root * cospi(theta); + float dev = 1.73205080756887729353f * phi_root * sinpi(theta); + return float3(2 * ncprod, -dev - ncprod, dev - ncprod) * scal - pz; + } +} + + +/* + * This function is not overflow-safe. Use with care. + */ +float4 solve_monic(float4 p) +{ + + // step 1: depress the input polynomial + float bias = p.w * 0.25f; + float3 qv = float3((-3.0f / 256.0f) * p.w * p.w, (1.0f / 8.0f) * p.w, (-3.0 / 8.0f)); + float3 rv = float3((1.0f / 16.0f) * p.z * p.w - (1.0f / 4.0f) * p.y, (-1.0f / 2.0f) * p.z, 0.0f); + float3 qx = float3(qv * p.w + rv) * p.w + p.xyz; + + // step 2: solve a cubic equation to get hold of a parameter p. + float3 monicp = float3(-qx.y * qx.y, (qx.z * qx.z) - (4.0f * qx.x), 2.0f * qx.z); + float4 v = float4(solve_monic(monicp), 1e-37f); + + // the cubic equation may have multiple solutions; at least one of them + // is numerically at least nonnegative (but may have become negative as a result of + // a roundoff error). We use fmax() to extract this value or a very small positive value. + float2 v2 = fmax(v.xy, v.zw); + float p2 = fmax(v2.x, v2.y); // p^2 + float pr = inversesqrt(p2); // 1/p + float pm = p2 * pr; // p + + // step 3: use the solution for the cubic equation to set up two quadratic equations; + // these two equations then result in the 4 possible roots. + float f1 = qx.z + p2; + float f2 = qx.y * pr; + float s = 0.5f * (f1 + f2); + float q = 0.5f * (f1 - f2); + + float4 res = float4(solve_monic(float2(q, pm)), + solve_monic(float2(s, -pm))); + + // finally, order the results and apply the bias. + if (res.x != res.x) + return res.zwxy - bias; + else + return res - bias; +} + + + +float2 transform(mat2 p, float2 q) +{ + return float2(dot(p.v[0], q), dot(p.v[1], q)); +} + + +float3 transform(mat3 p, float3 q) +{ + return float3(dot(p.v[0], q), dot(p.v[1], q), dot(p.v[2], q)); +} + + +float4 transform(mat4 p, float4 q) +{ + return float4(dot(p.v[0], q), dot(p.v[1], q), dot(p.v[2], q), dot(p.v[3], q)); +} + + + +mat2 adjugate(mat2 p) +{ + mat2 res; + res.v[0] = float2(p.v[1].y, -p.v[0].y); + res.v[1] = float2(-p.v[1].x, p.v[0].x); + return res; +} + + + +mat2 invert(mat2 p) +{ + float rdet = 1.0f / determinant(p); + mat2 res; + res.v[0] = float2(p.v[1].y, -p.v[0].y) * rdet; + res.v[1] = float2(-p.v[1].x, p.v[0].x) * rdet; + return res; +} + + + +mat3 adjugate(mat3 p) +{ + mat3 res; + float3 prd0 = cross(p.v[1], p.v[2]); + float3 prd1 = cross(p.v[2], p.v[0]); + float3 prd2 = cross(p.v[0], p.v[1]); + res.v[0] = float3(prd0.x, prd1.x, prd2.x); + res.v[1] = float3(prd0.y, prd1.y, prd2.y); + res.v[2] = float3(prd0.z, prd1.z, prd2.z); + return res; +} + + + +mat3 invert(mat3 p) +{ + float3 cross0 = cross(p.v[1], p.v[2]); + float det = dot(cross0, p.v[0]); + float rdet = 1.0f / det; + mat3 res; + float3 prd0 = cross0 * rdet; + float3 prd1 = cross(p.v[2], p.v[0]) * rdet; + float3 prd2 = cross(p.v[0], p.v[1]) * rdet; + res.v[0] = float3(prd0.x, prd1.x, prd2.x); + res.v[1] = float3(prd0.y, prd1.y, prd2.y); + res.v[2] = float3(prd0.z, prd1.z, prd2.z); + return res; +} + + + +mat4 adjugate(mat4 p) +{ + mat4 res; + + float3 bpc0 = cross(p.v[2].yzw, p.v[3].yzw); + float3 tpc0 = cross(p.v[0].yzw, p.v[1].yzw); + res.v[0] = float4(dot(bpc0, p.v[1].yzw), -dot(bpc0, p.v[0].yzw), dot(tpc0, p.v[3].yzw), -dot(tpc0, p.v[2].yzw)); + + float3 bpc1 = cross(p.v[2].xzw, p.v[3].xzw); + float3 tpc1 = cross(p.v[0].xzw, p.v[1].xzw); + res.v[1] = float4(-dot(bpc1, p.v[1].xzw), dot(bpc1, p.v[0].xzw), -dot(tpc1, p.v[3].xzw), dot(tpc1, p.v[2].xzw)); + + float3 bpc2 = cross(p.v[2].xyw, p.v[3].xyw); + float3 tpc2 = cross(p.v[0].xyw, p.v[1].xyw); + res.v[2] = float4(dot(bpc2, p.v[1].xyw), -dot(bpc2, p.v[0].xyw), dot(tpc2, p.v[3].xyw), -dot(tpc2, p.v[2].xyw)); + + float3 bpc3 = cross(p.v[2].xyz, p.v[3].xyz); + float3 tpc3 = cross(p.v[0].xyz, p.v[1].xyz); + res.v[3] = float4(-dot(bpc3, p.v[1].xyz), dot(bpc3, p.v[0].xyz), -dot(tpc3, p.v[3].xyz), dot(tpc3, p.v[2].xyz)); + + return res; +} + + + +mat4 invert(mat4 p) +{ + // cross products between the bottom two rows + float3 bpc0 = cross(p.v[2].yzw, p.v[3].yzw); + float3 bpc1 = cross(p.v[2].xzw, p.v[3].xzw); + float3 bpc2 = cross(p.v[2].xyw, p.v[3].xyw); + float3 bpc3 = cross(p.v[2].xyz, p.v[3].xyz); + + // dot-products for the top rows + float4 row1 = float4(dot(bpc0, p.v[1].yzw), + -dot(bpc1, p.v[1].xzw), + dot(bpc2, p.v[1].xyw), + -dot(bpc3, p.v[1].xyz)); + + float det = dot(p.v[0], row1); + float rdet = 1.0f / det; + + mat4 res; + + float3 tpc0 = cross(p.v[0].yzw, p.v[1].yzw); + res.v[0] = float4(row1.x, -dot(bpc0, p.v[0].yzw), dot(tpc0, p.v[3].yzw), -dot(tpc0, p.v[2].yzw)) * rdet; + + float3 tpc1 = cross(p.v[0].xzw, p.v[1].xzw); + res.v[1] = float4(row1.y, dot(bpc1, p.v[0].xzw), -dot(tpc1, p.v[3].xzw), dot(tpc1, p.v[2].xzw)) * rdet; + float3 tpc2 = cross(p.v[0].xyw, p.v[1].xyw); + + res.v[2] = float4(row1.z, -dot(bpc2, p.v[0].xyw), dot(tpc2, p.v[3].xyw), -dot(tpc2, p.v[2].xyw)) * rdet; + + float3 tpc3 = cross(p.v[0].xyz, p.v[1].xyz); + res.v[3] = float4(row1.w, dot(bpc3, p.v[0].xyz), -dot(tpc3, p.v[3].xyz), dot(tpc3, p.v[2].xyz)) * rdet; + + + return res; +} + + + +float2 eigenvalues(mat2 p) +{ + return solve_monic(characteristic_poly(p)); +} + +float3 eigenvalues(mat3 p) +{ + return solve_monic(characteristic_poly(p)); +} + +float4 eigenvalues(mat4 p) +{ + return solve_monic(characteristic_poly(p)); +} + +float2 eigenvector(mat2 p, float eigvl) +{ + // for a mat2, we first reverse-subtract the eigenvalue from the matrix diagonal, + // then return whichever row had the larger sum-of-absolute-values. + float4 v = float4(p.v[0], p.v[1]); + v.xw = eigvl - v.xw; + if (fabs(v.x) + fabs(v.y) > fabs(v.z) + fabs(v.w)) + return v.yx; + else + return v.wz; +} + + +float3 eigenvector(mat3 p, float eigvl) +{ + // for a mat3, we obtain the eigenvector as follows: + // step 1: subtract the eigenvalue from the matrix diagonal + // step 2: take two cross products between rows in the matrix + // step 3: return whichever of the cross products resulted in a longer vector. + + float3 r0 = p.v[0]; + float3 r1 = p.v[1]; + float3 r2 = p.v[2]; + + r0.x = r0.x - eigvl; + r1.y = r1.y - eigvl; + r2.z = r2.z - eigvl; + + float3 v1 = cross(r0, r1); + float3 v2 = cross(r1, r2); + + float len1 = dot(v1, v1); + float len2 = dot(v2, v2); + return len1 > len2 ? v1 : v2; +} + + +// generalized cross product: 3 vectors with 4 components each. +// The result is a vector that is perpendicular to all the three specified vectors. + +// it works in the sense that it produces a perpendicular-to-everything vector, +// but it has not been tested whether it points in the "right" direction. +float4 gcross(float4 p, float4 q, float4 r) +{ + return float4(dot(p.yzw, cross(q.yzw, r.yzw)), -dot(p.xzw, cross(q.xzw, r.xzw)), dot(p.xyw, cross(q.xyw, r.xyw)), -dot(p.xyz, cross(q.xyz, r.xyz))); +} + + + +float4 eigenvector(mat4 p, float eigvl) +{ + float4 r0 = p.v[0]; + float4 r1 = p.v[1]; + float4 r2 = p.v[2]; + float4 r3 = p.v[3]; + + r0.x = r0.x - eigvl; + r1.y = r1.y - eigvl; + r2.z = r2.z - eigvl; + r3.w = r3.w - eigvl; + + // generate four candidate vectors using the generalized cross product. + // These will in general point in the same direction (or 180 degree opposite), + // however they will have different lengths. Pick the longest one. + float3 tpc0 = cross(r0.yzw, r1.yzw); + float3 tpc1 = cross(r0.xzw, r1.xzw); + float3 tpc2 = cross(r0.xyw, r1.xyw); + float3 tpc3 = cross(r0.xyz, r1.xyz); + + float4 v1 = float4(dot(r2.yzw, tpc0), + -dot(r2.xzw, tpc1), + dot(r2.xyw, tpc2), + -dot(r2.xyz, tpc3)); + + float4 v2 = float4(dot(r3.yzw, tpc0), + -dot(r3.xzw, tpc1), + dot(r3.xyw, tpc2), + -dot(r3.xyz, tpc3)); + + float3 bpc0 = cross(r2.yzw, r3.yzw); + float3 bpc1 = cross(r2.xzw, r3.xzw); + float3 bpc2 = cross(r2.xyw, r3.xyw); + float3 bpc3 = cross(r2.xyz, r3.xyz); + + float4 v3 = float4(dot(r0.yzw, bpc0), + -dot(r0.xzw, bpc1), + dot(r0.xyw, bpc2), + -dot(r0.xyz, bpc3)); + + float4 v4 = float4(dot(r1.yzw, bpc0), + -dot(r1.xzw, bpc1), + dot(r1.xyw, bpc2), + -dot(r1.xyz, bpc3)); + + float len1 = dot(v1, v1); + float len2 = dot(v2, v2); + float len3 = dot(v3, v3); + float len4 = dot(v4, v4); + + if (fmax(len1, len2) > fmax(len3, len4)) + return len1 > len2 ? v1 : v2; + else + return len3 > len4 ? v3 : v4; +} + + +// matrix multiply + +mat2 operator *(mat2 a, mat2 b) +{ + mat2 res; + res.v[0] = a.v[0].x * b.v[0] + a.v[0].y * b.v[1]; + res.v[1] = a.v[1].x * b.v[0] + a.v[1].y * b.v[1]; + return res; +} + +mat3 operator *(mat3 a, mat3 b) +{ + mat3 res; + res.v[0] = a.v[0].x * b.v[0] + a.v[0].y * b.v[1] + a.v[0].z * b.v[2]; + res.v[1] = a.v[1].x * b.v[0] + a.v[1].y * b.v[1] + a.v[1].z * b.v[2]; + res.v[2] = a.v[2].x * b.v[0] + a.v[2].y * b.v[1] + a.v[2].z * b.v[2]; + return res; +} + +mat4 operator *(mat4 a, mat4 b) +{ + mat4 res; + res.v[0] = a.v[0].x * b.v[0] + a.v[0].y * b.v[1] + a.v[0].z * b.v[2] + a.v[0].w * b.v[3]; + res.v[1] = a.v[1].x * b.v[0] + a.v[1].y * b.v[1] + a.v[1].z * b.v[2] + a.v[1].w * b.v[3]; + res.v[2] = a.v[2].x * b.v[0] + a.v[2].y * b.v[1] + a.v[2].z * b.v[2] + a.v[2].w * b.v[3]; + res.v[3] = a.v[3].x * b.v[0] + a.v[3].y * b.v[1] + a.v[3].z * b.v[2] + a.v[3].w * b.v[3]; + return res; +} + + + +/************************* + +simple geometric functions + +*************************/ + + +// return parameter value for the point on the line closest to the specified point +float param_nearest_on_line(float2 point, line2 line) +{ + return dot(point - line.a, line.b) / dot(line.b, line.b); +} + +float param_nearest_on_line(float3 point, line3 line) +{ + return dot(point - line.a, line.b) / dot(line.b, line.b); +} + +float param_nearest_on_line(float4 point, line4 line) +{ + return dot(point - line.a, line.b) / dot(line.b, line.b); +} + + +// return distance between point and line +float point_line_distance(float2 point, line2 line) +{ + return distance(point, line.a + line.b * param_nearest_on_line(point, line)); +} + +float point_line_distance(float3 point, line3 line) +{ + return distance(point, line.a + line.b * param_nearest_on_line(point, line)); +} + +float point_line_distance(float4 point, line4 line) +{ + return distance(point, line.a + line.b * param_nearest_on_line(point, line)); +} + + +float point_line_distance_sqr(float2 point, line2 line) +{ + return distance_sqr(point, line.a + line.b * param_nearest_on_line(point, line)); +} + +float point_line_distance_sqr(float3 point, line3 line) +{ + return distance_sqr(point, line.a + line.b * param_nearest_on_line(point, line)); +} + +float point_line_distance_sqr(float4 point, line4 line) +{ + return distance_sqr(point, line.a + line.b * param_nearest_on_line(point, line)); +} + + + +// distance between plane/hyperplane in 3D and 4D +float point_plane_3d_distance(float3 point, plane_3d plane) +{ + return dot(point - plane.root_point, plane.normal); +} + + +float point_hyperplane_4d_distance(float4 point, hyperplane_4d plane) +{ + return dot(point - plane.root_point, plane.normal); +} + + +// helper functions to produce a 3D plane from three points and a 4D hyperplane from four points. +plane_3d generate_plane_from_points(float3 point0, float3 point1, float3 point2) +{ + plane_3d res; + res.root_point = point0; + res.normal = normalize(cross(point1 - point0, point2 - point0)); + return res; +} + +hyperplane_4d generate_hyperplane_from_points(float4 point0, float4 point1, float4 point2, float4 point3) +{ + hyperplane_4d res; + res.root_point = point0; + res.normal = normalize(gcross(point1 - point0, point2 - point0, point3 - point0)); + return res; +} + + diff --git a/third_party/astcenc/Source/mathlib.h b/third_party/astcenc/Source/mathlib.h new file mode 100644 index 0000000000..364ef07494 --- /dev/null +++ b/third_party/astcenc/Source/mathlib.h @@ -0,0 +1,200 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012, 2018 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Internal math library declarations for ASTC codec. + */ +/*----------------------------------------------------------------------------*/ + +#ifndef MATHLIB_H_INCLUDED + +#define MATHLIB_H_INCLUDED + +#include "vectypes.h" + +// basic OpenCL functions +float inversesqrt(float p); +float acospi(float p); +float sinpi(float p); +float cospi(float p); + +float nan(int p); + +#if __cplusplus < 201103L +float fmax(float p, float q); +float fmin(float p, float q); +#endif // C++11 + +float2 fmax(float2 p, float2 q); + +float3 fmax(float3 p, float3 q); + +float4 fmax(float4 p, float4 q); +float2 fmin(float2 p, float2 q); +float3 fmin(float3 p, float3 q); +float4 fmin(float4 p, float4 q); + +/* + float dot( float2 p, float2 q ); + float dot( float3 p, float3 q ); + float dot( float4 p, float4 q ); +*/ + +static inline float dot(float2 p, float2 q) +{ + return p.x * q.x + p.y * q.y; +} +static inline float dot(float3 p, float3 q) +{ + return p.x * q.x + p.y * q.y + p.z * q.z; +} +static inline float dot(float4 p, float4 q) +{ + return p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w; +} + + +float3 cross(float3 p, float3 q); +float4 cross(float4 p, float4 q); + +float length(float2 p); +float length(float3 p); +float length(float4 p); + +float length_sqr(float2 p); +float length_sqr(float3 p); +float length_sqr(float4 p); + +float distance(float2 p, float2 q); +float distance(float3 p, float3 q); +float distance(float4 p, float4 q); + +float distance_sqr(float2 p, float2 q); +float distance_sqr(float3 p, float3 q); +float distance_sqr(float4 p, float4 q); + +float2 normalize(float2 p); +float3 normalize(float3 p); +float4 normalize(float4 p); + + + +// functions other than just basic OpenCL functions + +float4 gcross(float4 p, float4 q, float4 r); + +struct mat2 +{ + float2 v[2]; +}; +struct mat3 +{ + float3 v[3]; +}; +struct mat4 +{ + float4 v[4]; +}; + +float trace(mat2 p); +float trace(mat3 p); +float trace(mat4 p); + +float determinant(mat2 p); +float determinant(mat3 p); +float determinant(mat4 p); + +float2 characteristic_poly(mat2 p); +float3 characteristic_poly(mat3 p); +float4 characteristic_poly(mat4 p); + +float2 solve_monic(float2 p); +float3 solve_monic(float3 p); +float4 solve_monic(float4 p); + +float2 transform(mat2 p, float2 q); +float3 transform(mat3 p, float3 q); +float4 transform(mat4 p, float4 q); + +mat2 adjugate(mat2 p); +mat3 adjugate(mat3 p); +mat4 adjugate(mat4 p); + +mat2 invert(mat2 p); +mat3 invert(mat3 p); +mat4 invert(mat4 p); + +float2 eigenvalues(mat2 p); +float3 eigenvalues(mat3 p); +float4 eigenvalues(mat4 p); + +float2 eigenvector(mat2 p, float eigvl); +float3 eigenvector(mat3 p, float eigvl); +float4 eigenvector(mat4 p, float eigvl); + +mat2 operator *(mat2 a, mat2 b); +mat3 operator *(mat3 a, mat3 b); +mat4 operator *(mat4 a, mat4 b); + + + +// parametric line, 2D: The line is given by line = a + b*t. +struct line2 +{ + float2 a; + float2 b; +}; + +// parametric line, 3D +struct line3 +{ + float3 a; + float3 b; +}; + +struct line4 +{ + float4 a; + float4 b; +}; + +// plane/hyperplane defined by a point and a normal vector +struct plane_3d +{ + float3 root_point; + float3 normal; // normalized +}; + +struct hyperplane_4d +{ + float4 root_point; + float4 normal; // normalized +}; + +float param_nearest_on_line(float2 point, line2 line); +float param_nearest_on_line(float3 point, line3 line); +float param_nearest_on_line(float4 point, line4 line); + +float point_line_distance(float2 point, line2 line); +float point_line_distance(float3 point, line3 line); +float point_line_distance(float4 point, line4 line); + +float point_line_distance_sqr(float2 point, line2 line); +float point_line_distance_sqr(float3 point, line3 line); +float point_line_distance_sqr(float4 point, line4 line); + +float point_plane_3d_distance(float3 point, plane_3d plane); +float point_hyperplane_4d_distance(float4 point, hyperplane_4d plane); + +plane_3d generate_plane_from_points(float3 point0, float3 point1, float3 point2); +hyperplane_4d generate_hyperplane_from_points(float4 point0, float4 point1, float4 point2, float4 point3); + + +#endif diff --git a/third_party/astcenc/Source/softfloat.cpp b/third_party/astcenc/Source/softfloat.cpp new file mode 100644 index 0000000000..11131bcac3 --- /dev/null +++ b/third_party/astcenc/Source/softfloat.cpp @@ -0,0 +1,398 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Soft IEEE-754 floating point library. + */ +/*----------------------------------------------------------------------------*/ + +#include "softfloat.h" + +#define SOFTFLOAT_INLINE + +/****************************************** + 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. */ +SOFTFLOAT_INLINE 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 +} + +static SOFTFLOAT_INLINE 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 SOFTFLOAT_INLINE 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 SOFTFLOAT_INLINE 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. */ +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_MB(a) INT32_C((a) | (1 << 31)) + static const int32_t tbl[64] = + { + WITH_MB(0x00000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), + INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), + INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), + INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), INT32_C(0x1C000), WITH_MB(0x38000), + WITH_MB(0x38000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), + INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), + INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), + INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), INT32_C(0x54000), WITH_MB(0x70000) + }; + + int32_t res = tbl[inpx >> 10]; + res += inpx; + + /* the normal cases: the MSB of 'res' is not set. */ + if (res >= 0) /* signed compare */ + return res << 13; + + /* Infinity and Zero: the bottom 10 bits of 'res' are clear. */ + if ((res & UINT32_C(0x3FF)) == 0) + return res << 13; + + /* NaN: the exponent field of 'inp' is not zero; NaNs must be quietened. */ + if ((inpx & 0x7C00) != 0) + return (res << 13) | UINT32_C(0x400000); + + /* the remaining cases are Denormals. */ + { + uint32_t sign = (inpx & UINT32_C(0x8000)) << 16; + uint32_t mskval = inpx & UINT32_C(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. */ + +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 ((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 (uint32_t) (-(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 ((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 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 (inp + vlx) >> 13; + + /* normal number, round-to-nearest-even. */ + case 33: + case 38: + p = inp + vlx; + p += (inp >> 13) & 1; + return 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 (((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000)) >> p) | vlx; + case 20: + case 26: + /* denormal, round away from zero. */ + p = 126 - ((inp >> 23) & 0xFF); + return 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 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 rtne_shift32((inp & UINT32_C(0x7FFFFF)) + UINT32_C(0x800000), p) | vlx; + } + + return 0; +} + + + +typedef union if32_ +{ + uint32_t u; + int32_t s; + float f; +} if32; + +/* convert from soft-float to native-float */ + +float sf16_to_float(sf16 p) +{ + if32 i; + i.u = sf16_to_sf32(p); + return i.f; +} + +/* convert from native-float to soft-float */ + +sf16 float_to_sf16(float p, roundmode rm) +{ + if32 i; + i.f = p; + return sf32_to_sf16(i.u, rm); +} diff --git a/third_party/astcenc/Source/softfloat.h b/third_party/astcenc/Source/softfloat.h new file mode 100644 index 0000000000..1cf9ba767f --- /dev/null +++ b/third_party/astcenc/Source/softfloat.h @@ -0,0 +1,95 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Soft IEEE-754 floating point library. + */ +/*----------------------------------------------------------------------------*/ + +#ifndef SOFTFLOAT_H_INCLUDED + +#define SOFTFLOAT_H_INCLUDED + +#if defined __cplusplus +extern "C" +{ +#endif + +#if defined __cplusplus && !defined(_MSC_VER) + + /* if compiling as C++, we need to define these macros in order to obtain all the macros in stdint.h . */ + #define __STDC_LIMIT_MACROS + #define __STDC_CONSTANT_MACROS + #include + +#else + + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef signed short int16_t; + typedef unsigned int uint32_t; + typedef signed int int32_t; + +#endif + + +uint32_t clz32(uint32_t p); + + +/* targets that don't have UINT32_C probably don't have the rest of C99s stdint.h */ +#ifndef UINT32_C + + #define PASTE(a) a + #define UINT64_C(a) PASTE(a##ULL) + #define UINT32_C(a) PASTE(a##U) + #define INT64_C(a) PASTE(a##LL) + #define INT32_C(a) a + + #define PRIX32 "X" + #define PRId32 "d" + #define PRIu32 "u" + #define PRIX64 "LX" + #define PRId64 "Ld" + #define PRIu64 "Lu" + +#endif + + /* 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; + + /* 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; + + /* narrowing float->float conversions */ + sf16 sf32_to_sf16(sf32, roundmode); + + /* widening float->float conversions */ + sf32 sf16_to_sf32(sf16); + + sf16 float_to_sf16(float, roundmode); + float sf16_to_float(sf16); + + +#if defined __cplusplus +} +#endif + +#endif diff --git a/third_party/astcenc/Source/vectypes.h b/third_party/astcenc/Source/vectypes.h new file mode 100644 index 0000000000..aa206d72ad --- /dev/null +++ b/third_party/astcenc/Source/vectypes.h @@ -0,0 +1,16209 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Template library for fixed-size vectors. + */ +/*----------------------------------------------------------------------------*/ + +#include +#include + +typedef unsigned int uint; +typedef unsigned short ushort; +typedef unsigned long ulong; +typedef unsigned char uchar; +typedef signed char schar; + +template < typename vtype > class vtype2; + +template < typename vtype > class vtype3; + +template < typename vtype > class vtype4; + +template < typename vtype > struct vtype2_xx_ref +{ + vtype2 < vtype > *v; + vtype2_xx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xy_ref +{ + vtype2 < vtype > *v; + vtype2_xy_ref(vtype2 < vtype > *p):v(p) + { + }; + inline vtype2_xy_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype2_yx_ref +{ + vtype2 < vtype > *v; + vtype2_yx_ref(vtype2 < vtype > *p):v(p) + { + }; + inline vtype2_yx_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype2_yy_ref +{ + vtype2 < vtype > *v; + vtype2_yy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xx_ref +{ + vtype3 < vtype > *v; + vtype3_xx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xy_ref +{ + vtype3 < vtype > *v; + vtype3_xy_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_xy_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype3_xz_ref +{ + vtype3 < vtype > *v; + vtype3_xz_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_xz_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype3_yx_ref +{ + vtype3 < vtype > *v; + vtype3_yx_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_yx_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype3_yy_ref +{ + vtype3 < vtype > *v; + vtype3_yy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yz_ref +{ + vtype3 < vtype > *v; + vtype3_yz_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_yz_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype3_zx_ref +{ + vtype3 < vtype > *v; + vtype3_zx_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_zx_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype3_zy_ref +{ + vtype3 < vtype > *v; + vtype3_zy_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_zy_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype3_zz_ref +{ + vtype3 < vtype > *v; + vtype3_zz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xx_ref +{ + vtype4 < vtype > *v; + vtype4_xx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xy_ref +{ + vtype4 < vtype > *v; + vtype4_xy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xy_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_xz_ref +{ + vtype4 < vtype > *v; + vtype4_xz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xz_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_xw_ref +{ + vtype4 < vtype > *v; + vtype4_xw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xw_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_yx_ref +{ + vtype4 < vtype > *v; + vtype4_yx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yx_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_yy_ref +{ + vtype4 < vtype > *v; + vtype4_yy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yz_ref +{ + vtype4 < vtype > *v; + vtype4_yz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yz_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_yw_ref +{ + vtype4 < vtype > *v; + vtype4_yw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yw_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_zx_ref +{ + vtype4 < vtype > *v; + vtype4_zx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zx_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_zy_ref +{ + vtype4 < vtype > *v; + vtype4_zy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zy_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_zz_ref +{ + vtype4 < vtype > *v; + vtype4_zz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zw_ref +{ + vtype4 < vtype > *v; + vtype4_zw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zw_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_wx_ref +{ + vtype4 < vtype > *v; + vtype4_wx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wx_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_wy_ref +{ + vtype4 < vtype > *v; + vtype4_wy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wy_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_wz_ref +{ + vtype4 < vtype > *v; + vtype4_wz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wz_ref & operator=(const vtype2 < vtype > &); +}; +template < typename vtype > struct vtype4_ww_ref +{ + vtype4 < vtype > *v; + vtype4_ww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xxx_ref +{ + vtype2 < vtype > *v; + vtype2_xxx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xxy_ref +{ + vtype2 < vtype > *v; + vtype2_xxy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xyx_ref +{ + vtype2 < vtype > *v; + vtype2_xyx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xyy_ref +{ + vtype2 < vtype > *v; + vtype2_xyy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yxx_ref +{ + vtype2 < vtype > *v; + vtype2_yxx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yxy_ref +{ + vtype2 < vtype > *v; + vtype2_yxy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yyx_ref +{ + vtype2 < vtype > *v; + vtype2_yyx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yyy_ref +{ + vtype2 < vtype > *v; + vtype2_yyy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxx_ref +{ + vtype3 < vtype > *v; + vtype3_xxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxy_ref +{ + vtype3 < vtype > *v; + vtype3_xxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxz_ref +{ + vtype3 < vtype > *v; + vtype3_xxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyx_ref +{ + vtype3 < vtype > *v; + vtype3_xyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyy_ref +{ + vtype3 < vtype > *v; + vtype3_xyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyz_ref +{ + vtype3 < vtype > *v; + vtype3_xyz_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_xyz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype3_xzx_ref +{ + vtype3 < vtype > *v; + vtype3_xzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzy_ref +{ + vtype3 < vtype > *v; + vtype3_xzy_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_xzy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype3_xzz_ref +{ + vtype3 < vtype > *v; + vtype3_xzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxx_ref +{ + vtype3 < vtype > *v; + vtype3_yxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxy_ref +{ + vtype3 < vtype > *v; + vtype3_yxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxz_ref +{ + vtype3 < vtype > *v; + vtype3_yxz_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_yxz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype3_yyx_ref +{ + vtype3 < vtype > *v; + vtype3_yyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyy_ref +{ + vtype3 < vtype > *v; + vtype3_yyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyz_ref +{ + vtype3 < vtype > *v; + vtype3_yyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzx_ref +{ + vtype3 < vtype > *v; + vtype3_yzx_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_yzx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype3_yzy_ref +{ + vtype3 < vtype > *v; + vtype3_yzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzz_ref +{ + vtype3 < vtype > *v; + vtype3_yzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxx_ref +{ + vtype3 < vtype > *v; + vtype3_zxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxy_ref +{ + vtype3 < vtype > *v; + vtype3_zxy_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_zxy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype3_zxz_ref +{ + vtype3 < vtype > *v; + vtype3_zxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyx_ref +{ + vtype3 < vtype > *v; + vtype3_zyx_ref(vtype3 < vtype > *p):v(p) + { + }; + inline vtype3_zyx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype3_zyy_ref +{ + vtype3 < vtype > *v; + vtype3_zyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyz_ref +{ + vtype3 < vtype > *v; + vtype3_zyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzx_ref +{ + vtype3 < vtype > *v; + vtype3_zzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzy_ref +{ + vtype3 < vtype > *v; + vtype3_zzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzz_ref +{ + vtype3 < vtype > *v; + vtype3_zzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxx_ref +{ + vtype4 < vtype > *v; + vtype4_xxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxy_ref +{ + vtype4 < vtype > *v; + vtype4_xxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxz_ref +{ + vtype4 < vtype > *v; + vtype4_xxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxw_ref +{ + vtype4 < vtype > *v; + vtype4_xxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyx_ref +{ + vtype4 < vtype > *v; + vtype4_xyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyy_ref +{ + vtype4 < vtype > *v; + vtype4_xyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyz_ref +{ + vtype4 < vtype > *v; + vtype4_xyz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xyz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_xyw_ref +{ + vtype4 < vtype > *v; + vtype4_xyw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xyw_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_xzx_ref +{ + vtype4 < vtype > *v; + vtype4_xzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzy_ref +{ + vtype4 < vtype > *v; + vtype4_xzy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xzy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_xzz_ref +{ + vtype4 < vtype > *v; + vtype4_xzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzw_ref +{ + vtype4 < vtype > *v; + vtype4_xzw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xzw_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_xwx_ref +{ + vtype4 < vtype > *v; + vtype4_xwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwy_ref +{ + vtype4 < vtype > *v; + vtype4_xwy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xwy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_xwz_ref +{ + vtype4 < vtype > *v; + vtype4_xwz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xwz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_xww_ref +{ + vtype4 < vtype > *v; + vtype4_xww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxx_ref +{ + vtype4 < vtype > *v; + vtype4_yxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxy_ref +{ + vtype4 < vtype > *v; + vtype4_yxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxz_ref +{ + vtype4 < vtype > *v; + vtype4_yxz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yxz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_yxw_ref +{ + vtype4 < vtype > *v; + vtype4_yxw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yxw_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_yyx_ref +{ + vtype4 < vtype > *v; + vtype4_yyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyy_ref +{ + vtype4 < vtype > *v; + vtype4_yyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyz_ref +{ + vtype4 < vtype > *v; + vtype4_yyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyw_ref +{ + vtype4 < vtype > *v; + vtype4_yyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzx_ref +{ + vtype4 < vtype > *v; + vtype4_yzx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yzx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_yzy_ref +{ + vtype4 < vtype > *v; + vtype4_yzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzz_ref +{ + vtype4 < vtype > *v; + vtype4_yzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzw_ref +{ + vtype4 < vtype > *v; + vtype4_yzw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yzw_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_ywx_ref +{ + vtype4 < vtype > *v; + vtype4_ywx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_ywx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_ywy_ref +{ + vtype4 < vtype > *v; + vtype4_ywy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywz_ref +{ + vtype4 < vtype > *v; + vtype4_ywz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_ywz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_yww_ref +{ + vtype4 < vtype > *v; + vtype4_yww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxx_ref +{ + vtype4 < vtype > *v; + vtype4_zxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxy_ref +{ + vtype4 < vtype > *v; + vtype4_zxy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zxy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_zxz_ref +{ + vtype4 < vtype > *v; + vtype4_zxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxw_ref +{ + vtype4 < vtype > *v; + vtype4_zxw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zxw_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_zyx_ref +{ + vtype4 < vtype > *v; + vtype4_zyx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zyx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_zyy_ref +{ + vtype4 < vtype > *v; + vtype4_zyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyz_ref +{ + vtype4 < vtype > *v; + vtype4_zyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyw_ref +{ + vtype4 < vtype > *v; + vtype4_zyw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zyw_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_zzx_ref +{ + vtype4 < vtype > *v; + vtype4_zzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzy_ref +{ + vtype4 < vtype > *v; + vtype4_zzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzz_ref +{ + vtype4 < vtype > *v; + vtype4_zzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzw_ref +{ + vtype4 < vtype > *v; + vtype4_zzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwx_ref +{ + vtype4 < vtype > *v; + vtype4_zwx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zwx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_zwy_ref +{ + vtype4 < vtype > *v; + vtype4_zwy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zwy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_zwz_ref +{ + vtype4 < vtype > *v; + vtype4_zwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zww_ref +{ + vtype4 < vtype > *v; + vtype4_zww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxx_ref +{ + vtype4 < vtype > *v; + vtype4_wxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxy_ref +{ + vtype4 < vtype > *v; + vtype4_wxy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wxy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_wxz_ref +{ + vtype4 < vtype > *v; + vtype4_wxz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wxz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_wxw_ref +{ + vtype4 < vtype > *v; + vtype4_wxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyx_ref +{ + vtype4 < vtype > *v; + vtype4_wyx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wyx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_wyy_ref +{ + vtype4 < vtype > *v; + vtype4_wyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyz_ref +{ + vtype4 < vtype > *v; + vtype4_wyz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wyz_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_wyw_ref +{ + vtype4 < vtype > *v; + vtype4_wyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzx_ref +{ + vtype4 < vtype > *v; + vtype4_wzx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wzx_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_wzy_ref +{ + vtype4 < vtype > *v; + vtype4_wzy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wzy_ref & operator=(const vtype3 < vtype > &); +}; +template < typename vtype > struct vtype4_wzz_ref +{ + vtype4 < vtype > *v; + vtype4_wzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzw_ref +{ + vtype4 < vtype > *v; + vtype4_wzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwx_ref +{ + vtype4 < vtype > *v; + vtype4_wwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwy_ref +{ + vtype4 < vtype > *v; + vtype4_wwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwz_ref +{ + vtype4 < vtype > *v; + vtype4_wwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_www_ref +{ + vtype4 < vtype > *v; + vtype4_www_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xxxx_ref +{ + vtype2 < vtype > *v; + vtype2_xxxx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xxxy_ref +{ + vtype2 < vtype > *v; + vtype2_xxxy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xxyx_ref +{ + vtype2 < vtype > *v; + vtype2_xxyx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xxyy_ref +{ + vtype2 < vtype > *v; + vtype2_xxyy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xyxx_ref +{ + vtype2 < vtype > *v; + vtype2_xyxx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xyxy_ref +{ + vtype2 < vtype > *v; + vtype2_xyxy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xyyx_ref +{ + vtype2 < vtype > *v; + vtype2_xyyx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_xyyy_ref +{ + vtype2 < vtype > *v; + vtype2_xyyy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yxxx_ref +{ + vtype2 < vtype > *v; + vtype2_yxxx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yxxy_ref +{ + vtype2 < vtype > *v; + vtype2_yxxy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yxyx_ref +{ + vtype2 < vtype > *v; + vtype2_yxyx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yxyy_ref +{ + vtype2 < vtype > *v; + vtype2_yxyy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yyxx_ref +{ + vtype2 < vtype > *v; + vtype2_yyxx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yyxy_ref +{ + vtype2 < vtype > *v; + vtype2_yyxy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yyyx_ref +{ + vtype2 < vtype > *v; + vtype2_yyyx_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype2_yyyy_ref +{ + vtype2 < vtype > *v; + vtype2_yyyy_ref(vtype2 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxxx_ref +{ + vtype3 < vtype > *v; + vtype3_xxxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxxy_ref +{ + vtype3 < vtype > *v; + vtype3_xxxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxxz_ref +{ + vtype3 < vtype > *v; + vtype3_xxxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxyx_ref +{ + vtype3 < vtype > *v; + vtype3_xxyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxyy_ref +{ + vtype3 < vtype > *v; + vtype3_xxyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxyz_ref +{ + vtype3 < vtype > *v; + vtype3_xxyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxzx_ref +{ + vtype3 < vtype > *v; + vtype3_xxzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxzy_ref +{ + vtype3 < vtype > *v; + vtype3_xxzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xxzz_ref +{ + vtype3 < vtype > *v; + vtype3_xxzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyxx_ref +{ + vtype3 < vtype > *v; + vtype3_xyxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyxy_ref +{ + vtype3 < vtype > *v; + vtype3_xyxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyxz_ref +{ + vtype3 < vtype > *v; + vtype3_xyxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyyx_ref +{ + vtype3 < vtype > *v; + vtype3_xyyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyyy_ref +{ + vtype3 < vtype > *v; + vtype3_xyyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyyz_ref +{ + vtype3 < vtype > *v; + vtype3_xyyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyzx_ref +{ + vtype3 < vtype > *v; + vtype3_xyzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyzy_ref +{ + vtype3 < vtype > *v; + vtype3_xyzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xyzz_ref +{ + vtype3 < vtype > *v; + vtype3_xyzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzxx_ref +{ + vtype3 < vtype > *v; + vtype3_xzxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzxy_ref +{ + vtype3 < vtype > *v; + vtype3_xzxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzxz_ref +{ + vtype3 < vtype > *v; + vtype3_xzxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzyx_ref +{ + vtype3 < vtype > *v; + vtype3_xzyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzyy_ref +{ + vtype3 < vtype > *v; + vtype3_xzyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzyz_ref +{ + vtype3 < vtype > *v; + vtype3_xzyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzzx_ref +{ + vtype3 < vtype > *v; + vtype3_xzzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzzy_ref +{ + vtype3 < vtype > *v; + vtype3_xzzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_xzzz_ref +{ + vtype3 < vtype > *v; + vtype3_xzzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxxx_ref +{ + vtype3 < vtype > *v; + vtype3_yxxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxxy_ref +{ + vtype3 < vtype > *v; + vtype3_yxxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxxz_ref +{ + vtype3 < vtype > *v; + vtype3_yxxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxyx_ref +{ + vtype3 < vtype > *v; + vtype3_yxyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxyy_ref +{ + vtype3 < vtype > *v; + vtype3_yxyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxyz_ref +{ + vtype3 < vtype > *v; + vtype3_yxyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxzx_ref +{ + vtype3 < vtype > *v; + vtype3_yxzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxzy_ref +{ + vtype3 < vtype > *v; + vtype3_yxzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yxzz_ref +{ + vtype3 < vtype > *v; + vtype3_yxzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyxx_ref +{ + vtype3 < vtype > *v; + vtype3_yyxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyxy_ref +{ + vtype3 < vtype > *v; + vtype3_yyxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyxz_ref +{ + vtype3 < vtype > *v; + vtype3_yyxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyyx_ref +{ + vtype3 < vtype > *v; + vtype3_yyyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyyy_ref +{ + vtype3 < vtype > *v; + vtype3_yyyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyyz_ref +{ + vtype3 < vtype > *v; + vtype3_yyyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyzx_ref +{ + vtype3 < vtype > *v; + vtype3_yyzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyzy_ref +{ + vtype3 < vtype > *v; + vtype3_yyzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yyzz_ref +{ + vtype3 < vtype > *v; + vtype3_yyzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzxx_ref +{ + vtype3 < vtype > *v; + vtype3_yzxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzxy_ref +{ + vtype3 < vtype > *v; + vtype3_yzxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzxz_ref +{ + vtype3 < vtype > *v; + vtype3_yzxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzyx_ref +{ + vtype3 < vtype > *v; + vtype3_yzyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzyy_ref +{ + vtype3 < vtype > *v; + vtype3_yzyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzyz_ref +{ + vtype3 < vtype > *v; + vtype3_yzyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzzx_ref +{ + vtype3 < vtype > *v; + vtype3_yzzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzzy_ref +{ + vtype3 < vtype > *v; + vtype3_yzzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_yzzz_ref +{ + vtype3 < vtype > *v; + vtype3_yzzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxxx_ref +{ + vtype3 < vtype > *v; + vtype3_zxxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxxy_ref +{ + vtype3 < vtype > *v; + vtype3_zxxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxxz_ref +{ + vtype3 < vtype > *v; + vtype3_zxxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxyx_ref +{ + vtype3 < vtype > *v; + vtype3_zxyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxyy_ref +{ + vtype3 < vtype > *v; + vtype3_zxyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxyz_ref +{ + vtype3 < vtype > *v; + vtype3_zxyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxzx_ref +{ + vtype3 < vtype > *v; + vtype3_zxzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxzy_ref +{ + vtype3 < vtype > *v; + vtype3_zxzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zxzz_ref +{ + vtype3 < vtype > *v; + vtype3_zxzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyxx_ref +{ + vtype3 < vtype > *v; + vtype3_zyxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyxy_ref +{ + vtype3 < vtype > *v; + vtype3_zyxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyxz_ref +{ + vtype3 < vtype > *v; + vtype3_zyxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyyx_ref +{ + vtype3 < vtype > *v; + vtype3_zyyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyyy_ref +{ + vtype3 < vtype > *v; + vtype3_zyyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyyz_ref +{ + vtype3 < vtype > *v; + vtype3_zyyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyzx_ref +{ + vtype3 < vtype > *v; + vtype3_zyzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyzy_ref +{ + vtype3 < vtype > *v; + vtype3_zyzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zyzz_ref +{ + vtype3 < vtype > *v; + vtype3_zyzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzxx_ref +{ + vtype3 < vtype > *v; + vtype3_zzxx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzxy_ref +{ + vtype3 < vtype > *v; + vtype3_zzxy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzxz_ref +{ + vtype3 < vtype > *v; + vtype3_zzxz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzyx_ref +{ + vtype3 < vtype > *v; + vtype3_zzyx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzyy_ref +{ + vtype3 < vtype > *v; + vtype3_zzyy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzyz_ref +{ + vtype3 < vtype > *v; + vtype3_zzyz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzzx_ref +{ + vtype3 < vtype > *v; + vtype3_zzzx_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzzy_ref +{ + vtype3 < vtype > *v; + vtype3_zzzy_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype3_zzzz_ref +{ + vtype3 < vtype > *v; + vtype3_zzzz_ref(vtype3 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxxx_ref +{ + vtype4 < vtype > *v; + vtype4_xxxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxxy_ref +{ + vtype4 < vtype > *v; + vtype4_xxxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxxz_ref +{ + vtype4 < vtype > *v; + vtype4_xxxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxxw_ref +{ + vtype4 < vtype > *v; + vtype4_xxxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxyx_ref +{ + vtype4 < vtype > *v; + vtype4_xxyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxyy_ref +{ + vtype4 < vtype > *v; + vtype4_xxyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxyz_ref +{ + vtype4 < vtype > *v; + vtype4_xxyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxyw_ref +{ + vtype4 < vtype > *v; + vtype4_xxyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxzx_ref +{ + vtype4 < vtype > *v; + vtype4_xxzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxzy_ref +{ + vtype4 < vtype > *v; + vtype4_xxzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxzz_ref +{ + vtype4 < vtype > *v; + vtype4_xxzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxzw_ref +{ + vtype4 < vtype > *v; + vtype4_xxzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxwx_ref +{ + vtype4 < vtype > *v; + vtype4_xxwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxwy_ref +{ + vtype4 < vtype > *v; + vtype4_xxwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxwz_ref +{ + vtype4 < vtype > *v; + vtype4_xxwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xxww_ref +{ + vtype4 < vtype > *v; + vtype4_xxww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyxx_ref +{ + vtype4 < vtype > *v; + vtype4_xyxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyxy_ref +{ + vtype4 < vtype > *v; + vtype4_xyxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyxz_ref +{ + vtype4 < vtype > *v; + vtype4_xyxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyxw_ref +{ + vtype4 < vtype > *v; + vtype4_xyxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyyx_ref +{ + vtype4 < vtype > *v; + vtype4_xyyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyyy_ref +{ + vtype4 < vtype > *v; + vtype4_xyyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyyz_ref +{ + vtype4 < vtype > *v; + vtype4_xyyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyyw_ref +{ + vtype4 < vtype > *v; + vtype4_xyyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyzx_ref +{ + vtype4 < vtype > *v; + vtype4_xyzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyzy_ref +{ + vtype4 < vtype > *v; + vtype4_xyzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyzz_ref +{ + vtype4 < vtype > *v; + vtype4_xyzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xyzw_ref +{ + vtype4 < vtype > *v; + vtype4_xyzw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xyzw_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_xywx_ref +{ + vtype4 < vtype > *v; + vtype4_xywx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xywy_ref +{ + vtype4 < vtype > *v; + vtype4_xywy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xywz_ref +{ + vtype4 < vtype > *v; + vtype4_xywz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xywz_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_xyww_ref +{ + vtype4 < vtype > *v; + vtype4_xyww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzxx_ref +{ + vtype4 < vtype > *v; + vtype4_xzxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzxy_ref +{ + vtype4 < vtype > *v; + vtype4_xzxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzxz_ref +{ + vtype4 < vtype > *v; + vtype4_xzxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzxw_ref +{ + vtype4 < vtype > *v; + vtype4_xzxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzyx_ref +{ + vtype4 < vtype > *v; + vtype4_xzyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzyy_ref +{ + vtype4 < vtype > *v; + vtype4_xzyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzyz_ref +{ + vtype4 < vtype > *v; + vtype4_xzyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzyw_ref +{ + vtype4 < vtype > *v; + vtype4_xzyw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xzyw_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_xzzx_ref +{ + vtype4 < vtype > *v; + vtype4_xzzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzzy_ref +{ + vtype4 < vtype > *v; + vtype4_xzzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzzz_ref +{ + vtype4 < vtype > *v; + vtype4_xzzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzzw_ref +{ + vtype4 < vtype > *v; + vtype4_xzzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzwx_ref +{ + vtype4 < vtype > *v; + vtype4_xzwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzwy_ref +{ + vtype4 < vtype > *v; + vtype4_xzwy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xzwy_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_xzwz_ref +{ + vtype4 < vtype > *v; + vtype4_xzwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xzww_ref +{ + vtype4 < vtype > *v; + vtype4_xzww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwxx_ref +{ + vtype4 < vtype > *v; + vtype4_xwxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwxy_ref +{ + vtype4 < vtype > *v; + vtype4_xwxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwxz_ref +{ + vtype4 < vtype > *v; + vtype4_xwxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwxw_ref +{ + vtype4 < vtype > *v; + vtype4_xwxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwyx_ref +{ + vtype4 < vtype > *v; + vtype4_xwyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwyy_ref +{ + vtype4 < vtype > *v; + vtype4_xwyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwyz_ref +{ + vtype4 < vtype > *v; + vtype4_xwyz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xwyz_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_xwyw_ref +{ + vtype4 < vtype > *v; + vtype4_xwyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwzx_ref +{ + vtype4 < vtype > *v; + vtype4_xwzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwzy_ref +{ + vtype4 < vtype > *v; + vtype4_xwzy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_xwzy_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_xwzz_ref +{ + vtype4 < vtype > *v; + vtype4_xwzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwzw_ref +{ + vtype4 < vtype > *v; + vtype4_xwzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwwx_ref +{ + vtype4 < vtype > *v; + vtype4_xwwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwwy_ref +{ + vtype4 < vtype > *v; + vtype4_xwwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwwz_ref +{ + vtype4 < vtype > *v; + vtype4_xwwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_xwww_ref +{ + vtype4 < vtype > *v; + vtype4_xwww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxxx_ref +{ + vtype4 < vtype > *v; + vtype4_yxxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxxy_ref +{ + vtype4 < vtype > *v; + vtype4_yxxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxxz_ref +{ + vtype4 < vtype > *v; + vtype4_yxxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxxw_ref +{ + vtype4 < vtype > *v; + vtype4_yxxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxyx_ref +{ + vtype4 < vtype > *v; + vtype4_yxyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxyy_ref +{ + vtype4 < vtype > *v; + vtype4_yxyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxyz_ref +{ + vtype4 < vtype > *v; + vtype4_yxyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxyw_ref +{ + vtype4 < vtype > *v; + vtype4_yxyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxzx_ref +{ + vtype4 < vtype > *v; + vtype4_yxzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxzy_ref +{ + vtype4 < vtype > *v; + vtype4_yxzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxzz_ref +{ + vtype4 < vtype > *v; + vtype4_yxzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxzw_ref +{ + vtype4 < vtype > *v; + vtype4_yxzw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yxzw_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_yxwx_ref +{ + vtype4 < vtype > *v; + vtype4_yxwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxwy_ref +{ + vtype4 < vtype > *v; + vtype4_yxwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yxwz_ref +{ + vtype4 < vtype > *v; + vtype4_yxwz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yxwz_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_yxww_ref +{ + vtype4 < vtype > *v; + vtype4_yxww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyxx_ref +{ + vtype4 < vtype > *v; + vtype4_yyxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyxy_ref +{ + vtype4 < vtype > *v; + vtype4_yyxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyxz_ref +{ + vtype4 < vtype > *v; + vtype4_yyxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyxw_ref +{ + vtype4 < vtype > *v; + vtype4_yyxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyyx_ref +{ + vtype4 < vtype > *v; + vtype4_yyyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyyy_ref +{ + vtype4 < vtype > *v; + vtype4_yyyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyyz_ref +{ + vtype4 < vtype > *v; + vtype4_yyyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyyw_ref +{ + vtype4 < vtype > *v; + vtype4_yyyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyzx_ref +{ + vtype4 < vtype > *v; + vtype4_yyzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyzy_ref +{ + vtype4 < vtype > *v; + vtype4_yyzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyzz_ref +{ + vtype4 < vtype > *v; + vtype4_yyzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyzw_ref +{ + vtype4 < vtype > *v; + vtype4_yyzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yywx_ref +{ + vtype4 < vtype > *v; + vtype4_yywx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yywy_ref +{ + vtype4 < vtype > *v; + vtype4_yywy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yywz_ref +{ + vtype4 < vtype > *v; + vtype4_yywz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yyww_ref +{ + vtype4 < vtype > *v; + vtype4_yyww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzxx_ref +{ + vtype4 < vtype > *v; + vtype4_yzxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzxy_ref +{ + vtype4 < vtype > *v; + vtype4_yzxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzxz_ref +{ + vtype4 < vtype > *v; + vtype4_yzxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzxw_ref +{ + vtype4 < vtype > *v; + vtype4_yzxw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yzxw_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_yzyx_ref +{ + vtype4 < vtype > *v; + vtype4_yzyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzyy_ref +{ + vtype4 < vtype > *v; + vtype4_yzyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzyz_ref +{ + vtype4 < vtype > *v; + vtype4_yzyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzyw_ref +{ + vtype4 < vtype > *v; + vtype4_yzyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzzx_ref +{ + vtype4 < vtype > *v; + vtype4_yzzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzzy_ref +{ + vtype4 < vtype > *v; + vtype4_yzzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzzz_ref +{ + vtype4 < vtype > *v; + vtype4_yzzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzzw_ref +{ + vtype4 < vtype > *v; + vtype4_yzzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzwx_ref +{ + vtype4 < vtype > *v; + vtype4_yzwx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_yzwx_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_yzwy_ref +{ + vtype4 < vtype > *v; + vtype4_yzwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzwz_ref +{ + vtype4 < vtype > *v; + vtype4_yzwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_yzww_ref +{ + vtype4 < vtype > *v; + vtype4_yzww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywxx_ref +{ + vtype4 < vtype > *v; + vtype4_ywxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywxy_ref +{ + vtype4 < vtype > *v; + vtype4_ywxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywxz_ref +{ + vtype4 < vtype > *v; + vtype4_ywxz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_ywxz_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_ywxw_ref +{ + vtype4 < vtype > *v; + vtype4_ywxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywyx_ref +{ + vtype4 < vtype > *v; + vtype4_ywyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywyy_ref +{ + vtype4 < vtype > *v; + vtype4_ywyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywyz_ref +{ + vtype4 < vtype > *v; + vtype4_ywyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywyw_ref +{ + vtype4 < vtype > *v; + vtype4_ywyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywzx_ref +{ + vtype4 < vtype > *v; + vtype4_ywzx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_ywzx_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_ywzy_ref +{ + vtype4 < vtype > *v; + vtype4_ywzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywzz_ref +{ + vtype4 < vtype > *v; + vtype4_ywzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywzw_ref +{ + vtype4 < vtype > *v; + vtype4_ywzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywwx_ref +{ + vtype4 < vtype > *v; + vtype4_ywwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywwy_ref +{ + vtype4 < vtype > *v; + vtype4_ywwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywwz_ref +{ + vtype4 < vtype > *v; + vtype4_ywwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_ywww_ref +{ + vtype4 < vtype > *v; + vtype4_ywww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxxx_ref +{ + vtype4 < vtype > *v; + vtype4_zxxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxxy_ref +{ + vtype4 < vtype > *v; + vtype4_zxxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxxz_ref +{ + vtype4 < vtype > *v; + vtype4_zxxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxxw_ref +{ + vtype4 < vtype > *v; + vtype4_zxxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxyx_ref +{ + vtype4 < vtype > *v; + vtype4_zxyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxyy_ref +{ + vtype4 < vtype > *v; + vtype4_zxyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxyz_ref +{ + vtype4 < vtype > *v; + vtype4_zxyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxyw_ref +{ + vtype4 < vtype > *v; + vtype4_zxyw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zxyw_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_zxzx_ref +{ + vtype4 < vtype > *v; + vtype4_zxzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxzy_ref +{ + vtype4 < vtype > *v; + vtype4_zxzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxzz_ref +{ + vtype4 < vtype > *v; + vtype4_zxzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxzw_ref +{ + vtype4 < vtype > *v; + vtype4_zxzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxwx_ref +{ + vtype4 < vtype > *v; + vtype4_zxwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxwy_ref +{ + vtype4 < vtype > *v; + vtype4_zxwy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zxwy_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_zxwz_ref +{ + vtype4 < vtype > *v; + vtype4_zxwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zxww_ref +{ + vtype4 < vtype > *v; + vtype4_zxww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyxx_ref +{ + vtype4 < vtype > *v; + vtype4_zyxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyxy_ref +{ + vtype4 < vtype > *v; + vtype4_zyxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyxz_ref +{ + vtype4 < vtype > *v; + vtype4_zyxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyxw_ref +{ + vtype4 < vtype > *v; + vtype4_zyxw_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zyxw_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_zyyx_ref +{ + vtype4 < vtype > *v; + vtype4_zyyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyyy_ref +{ + vtype4 < vtype > *v; + vtype4_zyyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyyz_ref +{ + vtype4 < vtype > *v; + vtype4_zyyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyyw_ref +{ + vtype4 < vtype > *v; + vtype4_zyyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyzx_ref +{ + vtype4 < vtype > *v; + vtype4_zyzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyzy_ref +{ + vtype4 < vtype > *v; + vtype4_zyzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyzz_ref +{ + vtype4 < vtype > *v; + vtype4_zyzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyzw_ref +{ + vtype4 < vtype > *v; + vtype4_zyzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zywx_ref +{ + vtype4 < vtype > *v; + vtype4_zywx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zywx_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_zywy_ref +{ + vtype4 < vtype > *v; + vtype4_zywy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zywz_ref +{ + vtype4 < vtype > *v; + vtype4_zywz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zyww_ref +{ + vtype4 < vtype > *v; + vtype4_zyww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzxx_ref +{ + vtype4 < vtype > *v; + vtype4_zzxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzxy_ref +{ + vtype4 < vtype > *v; + vtype4_zzxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzxz_ref +{ + vtype4 < vtype > *v; + vtype4_zzxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzxw_ref +{ + vtype4 < vtype > *v; + vtype4_zzxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzyx_ref +{ + vtype4 < vtype > *v; + vtype4_zzyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzyy_ref +{ + vtype4 < vtype > *v; + vtype4_zzyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzyz_ref +{ + vtype4 < vtype > *v; + vtype4_zzyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzyw_ref +{ + vtype4 < vtype > *v; + vtype4_zzyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzzx_ref +{ + vtype4 < vtype > *v; + vtype4_zzzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzzy_ref +{ + vtype4 < vtype > *v; + vtype4_zzzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzzz_ref +{ + vtype4 < vtype > *v; + vtype4_zzzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzzw_ref +{ + vtype4 < vtype > *v; + vtype4_zzzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzwx_ref +{ + vtype4 < vtype > *v; + vtype4_zzwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzwy_ref +{ + vtype4 < vtype > *v; + vtype4_zzwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzwz_ref +{ + vtype4 < vtype > *v; + vtype4_zzwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zzww_ref +{ + vtype4 < vtype > *v; + vtype4_zzww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwxx_ref +{ + vtype4 < vtype > *v; + vtype4_zwxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwxy_ref +{ + vtype4 < vtype > *v; + vtype4_zwxy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zwxy_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_zwxz_ref +{ + vtype4 < vtype > *v; + vtype4_zwxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwxw_ref +{ + vtype4 < vtype > *v; + vtype4_zwxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwyx_ref +{ + vtype4 < vtype > *v; + vtype4_zwyx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_zwyx_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_zwyy_ref +{ + vtype4 < vtype > *v; + vtype4_zwyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwyz_ref +{ + vtype4 < vtype > *v; + vtype4_zwyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwyw_ref +{ + vtype4 < vtype > *v; + vtype4_zwyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwzx_ref +{ + vtype4 < vtype > *v; + vtype4_zwzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwzy_ref +{ + vtype4 < vtype > *v; + vtype4_zwzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwzz_ref +{ + vtype4 < vtype > *v; + vtype4_zwzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwzw_ref +{ + vtype4 < vtype > *v; + vtype4_zwzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwwx_ref +{ + vtype4 < vtype > *v; + vtype4_zwwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwwy_ref +{ + vtype4 < vtype > *v; + vtype4_zwwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwwz_ref +{ + vtype4 < vtype > *v; + vtype4_zwwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_zwww_ref +{ + vtype4 < vtype > *v; + vtype4_zwww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxxx_ref +{ + vtype4 < vtype > *v; + vtype4_wxxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxxy_ref +{ + vtype4 < vtype > *v; + vtype4_wxxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxxz_ref +{ + vtype4 < vtype > *v; + vtype4_wxxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxxw_ref +{ + vtype4 < vtype > *v; + vtype4_wxxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxyx_ref +{ + vtype4 < vtype > *v; + vtype4_wxyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxyy_ref +{ + vtype4 < vtype > *v; + vtype4_wxyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxyz_ref +{ + vtype4 < vtype > *v; + vtype4_wxyz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wxyz_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_wxyw_ref +{ + vtype4 < vtype > *v; + vtype4_wxyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxzx_ref +{ + vtype4 < vtype > *v; + vtype4_wxzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxzy_ref +{ + vtype4 < vtype > *v; + vtype4_wxzy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wxzy_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_wxzz_ref +{ + vtype4 < vtype > *v; + vtype4_wxzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxzw_ref +{ + vtype4 < vtype > *v; + vtype4_wxzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxwx_ref +{ + vtype4 < vtype > *v; + vtype4_wxwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxwy_ref +{ + vtype4 < vtype > *v; + vtype4_wxwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxwz_ref +{ + vtype4 < vtype > *v; + vtype4_wxwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wxww_ref +{ + vtype4 < vtype > *v; + vtype4_wxww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyxx_ref +{ + vtype4 < vtype > *v; + vtype4_wyxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyxy_ref +{ + vtype4 < vtype > *v; + vtype4_wyxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyxz_ref +{ + vtype4 < vtype > *v; + vtype4_wyxz_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wyxz_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_wyxw_ref +{ + vtype4 < vtype > *v; + vtype4_wyxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyyx_ref +{ + vtype4 < vtype > *v; + vtype4_wyyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyyy_ref +{ + vtype4 < vtype > *v; + vtype4_wyyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyyz_ref +{ + vtype4 < vtype > *v; + vtype4_wyyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyyw_ref +{ + vtype4 < vtype > *v; + vtype4_wyyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyzx_ref +{ + vtype4 < vtype > *v; + vtype4_wyzx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wyzx_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_wyzy_ref +{ + vtype4 < vtype > *v; + vtype4_wyzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyzz_ref +{ + vtype4 < vtype > *v; + vtype4_wyzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyzw_ref +{ + vtype4 < vtype > *v; + vtype4_wyzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wywx_ref +{ + vtype4 < vtype > *v; + vtype4_wywx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wywy_ref +{ + vtype4 < vtype > *v; + vtype4_wywy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wywz_ref +{ + vtype4 < vtype > *v; + vtype4_wywz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wyww_ref +{ + vtype4 < vtype > *v; + vtype4_wyww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzxx_ref +{ + vtype4 < vtype > *v; + vtype4_wzxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzxy_ref +{ + vtype4 < vtype > *v; + vtype4_wzxy_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wzxy_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_wzxz_ref +{ + vtype4 < vtype > *v; + vtype4_wzxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzxw_ref +{ + vtype4 < vtype > *v; + vtype4_wzxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzyx_ref +{ + vtype4 < vtype > *v; + vtype4_wzyx_ref(vtype4 < vtype > *p):v(p) + { + }; + inline vtype4_wzyx_ref & operator=(const vtype4 < vtype > &); +}; +template < typename vtype > struct vtype4_wzyy_ref +{ + vtype4 < vtype > *v; + vtype4_wzyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzyz_ref +{ + vtype4 < vtype > *v; + vtype4_wzyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzyw_ref +{ + vtype4 < vtype > *v; + vtype4_wzyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzzx_ref +{ + vtype4 < vtype > *v; + vtype4_wzzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzzy_ref +{ + vtype4 < vtype > *v; + vtype4_wzzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzzz_ref +{ + vtype4 < vtype > *v; + vtype4_wzzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzzw_ref +{ + vtype4 < vtype > *v; + vtype4_wzzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzwx_ref +{ + vtype4 < vtype > *v; + vtype4_wzwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzwy_ref +{ + vtype4 < vtype > *v; + vtype4_wzwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzwz_ref +{ + vtype4 < vtype > *v; + vtype4_wzwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wzww_ref +{ + vtype4 < vtype > *v; + vtype4_wzww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwxx_ref +{ + vtype4 < vtype > *v; + vtype4_wwxx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwxy_ref +{ + vtype4 < vtype > *v; + vtype4_wwxy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwxz_ref +{ + vtype4 < vtype > *v; + vtype4_wwxz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwxw_ref +{ + vtype4 < vtype > *v; + vtype4_wwxw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwyx_ref +{ + vtype4 < vtype > *v; + vtype4_wwyx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwyy_ref +{ + vtype4 < vtype > *v; + vtype4_wwyy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwyz_ref +{ + vtype4 < vtype > *v; + vtype4_wwyz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwyw_ref +{ + vtype4 < vtype > *v; + vtype4_wwyw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwzx_ref +{ + vtype4 < vtype > *v; + vtype4_wwzx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwzy_ref +{ + vtype4 < vtype > *v; + vtype4_wwzy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwzz_ref +{ + vtype4 < vtype > *v; + vtype4_wwzz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwzw_ref +{ + vtype4 < vtype > *v; + vtype4_wwzw_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwwx_ref +{ + vtype4 < vtype > *v; + vtype4_wwwx_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwwy_ref +{ + vtype4 < vtype > *v; + vtype4_wwwy_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwwz_ref +{ + vtype4 < vtype > *v; + vtype4_wwwz_ref(vtype4 < vtype > *p):v(p) + { + }; +}; +template < typename vtype > struct vtype4_wwww_ref +{ + vtype4 < vtype > *v; + vtype4_wwww_ref(vtype4 < vtype > *p):v(p) + { + }; +}; + +template < typename vtype > class vtype2 +{ + public: + vtype x, y; + vtype2() + { + }; + vtype2(vtype p, vtype q):x(p), y(q) + { + }; + vtype2(const vtype2 & p):x(p.x), y(p.y) + { + }; + inline vtype2(const vtype2_xx_ref < vtype > &v); + inline vtype2(const vtype2_xy_ref < vtype > &v); + inline vtype2(const vtype2_yx_ref < vtype > &v); + inline vtype2(const vtype2_yy_ref < vtype > &v); + inline vtype2(const vtype3_xx_ref < vtype > &v); + inline vtype2(const vtype3_xy_ref < vtype > &v); + inline vtype2(const vtype3_xz_ref < vtype > &v); + inline vtype2(const vtype3_yx_ref < vtype > &v); + inline vtype2(const vtype3_yy_ref < vtype > &v); + inline vtype2(const vtype3_yz_ref < vtype > &v); + inline vtype2(const vtype3_zx_ref < vtype > &v); + inline vtype2(const vtype3_zy_ref < vtype > &v); + inline vtype2(const vtype3_zz_ref < vtype > &v); + inline vtype2(const vtype4_xx_ref < vtype > &v); + inline vtype2(const vtype4_xy_ref < vtype > &v); + inline vtype2(const vtype4_xz_ref < vtype > &v); + inline vtype2(const vtype4_xw_ref < vtype > &v); + inline vtype2(const vtype4_yx_ref < vtype > &v); + inline vtype2(const vtype4_yy_ref < vtype > &v); + inline vtype2(const vtype4_yz_ref < vtype > &v); + inline vtype2(const vtype4_yw_ref < vtype > &v); + inline vtype2(const vtype4_zx_ref < vtype > &v); + inline vtype2(const vtype4_zy_ref < vtype > &v); + inline vtype2(const vtype4_zz_ref < vtype > &v); + inline vtype2(const vtype4_zw_ref < vtype > &v); + inline vtype2(const vtype4_wx_ref < vtype > &v); + inline vtype2(const vtype4_wy_ref < vtype > &v); + inline vtype2(const vtype4_wz_ref < vtype > &v); + inline vtype2(const vtype4_ww_ref < vtype > &v); + vtype2_xx_ref < vtype > xx() + { + return vtype2_xx_ref < vtype > (this); + } + vtype2_xy_ref < vtype > xy() + { + return vtype2_xy_ref < vtype > (this); + } + vtype2_yx_ref < vtype > yx() + { + return vtype2_yx_ref < vtype > (this); + } + vtype2_yy_ref < vtype > yy() + { + return vtype2_yy_ref < vtype > (this); + } + vtype2_xxx_ref < vtype > xxx() + { + return vtype2_xxx_ref < vtype > (this); + } + vtype2_xxy_ref < vtype > xxy() + { + return vtype2_xxy_ref < vtype > (this); + } + vtype2_xyx_ref < vtype > xyx() + { + return vtype2_xyx_ref < vtype > (this); + } + vtype2_xyy_ref < vtype > xyy() + { + return vtype2_xyy_ref < vtype > (this); + } + vtype2_yxx_ref < vtype > yxx() + { + return vtype2_yxx_ref < vtype > (this); + } + vtype2_yxy_ref < vtype > yxy() + { + return vtype2_yxy_ref < vtype > (this); + } + vtype2_yyx_ref < vtype > yyx() + { + return vtype2_yyx_ref < vtype > (this); + } + vtype2_yyy_ref < vtype > yyy() + { + return vtype2_yyy_ref < vtype > (this); + } + vtype2_xxxx_ref < vtype > xxxx() + { + return vtype2_xxxx_ref < vtype > (this); + } + vtype2_xxxy_ref < vtype > xxxy() + { + return vtype2_xxxy_ref < vtype > (this); + } + vtype2_xxyx_ref < vtype > xxyx() + { + return vtype2_xxyx_ref < vtype > (this); + } + vtype2_xxyy_ref < vtype > xxyy() + { + return vtype2_xxyy_ref < vtype > (this); + } + vtype2_xyxx_ref < vtype > xyxx() + { + return vtype2_xyxx_ref < vtype > (this); + } + vtype2_xyxy_ref < vtype > xyxy() + { + return vtype2_xyxy_ref < vtype > (this); + } + vtype2_xyyx_ref < vtype > xyyx() + { + return vtype2_xyyx_ref < vtype > (this); + } + vtype2_xyyy_ref < vtype > xyyy() + { + return vtype2_xyyy_ref < vtype > (this); + } + vtype2_yxxx_ref < vtype > yxxx() + { + return vtype2_yxxx_ref < vtype > (this); + } + vtype2_yxxy_ref < vtype > yxxy() + { + return vtype2_yxxy_ref < vtype > (this); + } + vtype2_yxyx_ref < vtype > yxyx() + { + return vtype2_yxyx_ref < vtype > (this); + } + vtype2_yxyy_ref < vtype > yxyy() + { + return vtype2_yxyy_ref < vtype > (this); + } + vtype2_yyxx_ref < vtype > yyxx() + { + return vtype2_yyxx_ref < vtype > (this); + } + vtype2_yyxy_ref < vtype > yyxy() + { + return vtype2_yyxy_ref < vtype > (this); + } + vtype2_yyyx_ref < vtype > yyyx() + { + return vtype2_yyyx_ref < vtype > (this); + } + vtype2_yyyy_ref < vtype > yyyy() + { + return vtype2_yyyy_ref < vtype > (this); + } +}; + +template < typename vtype > class vtype3 +{ + public: + vtype x, y, z; + vtype3() + { + }; + vtype3(vtype p, vtype q, vtype r):x(p), y(q), z(r) + { + }; + vtype3(const vtype3 & p):x(p.x), y(p.y), z(p.z) + { + }; + vtype3(vtype p, const vtype2 < vtype > &q):x(p), y(q.x), z(q.y) + { + }; + vtype3(const vtype2 < vtype > &p, vtype q):x(p.x), y(p.y), z(q) + { + }; + inline vtype3(const vtype2_xxx_ref < vtype > &v); + inline vtype3(const vtype2_xxy_ref < vtype > &v); + inline vtype3(const vtype2_xyx_ref < vtype > &v); + inline vtype3(const vtype2_xyy_ref < vtype > &v); + inline vtype3(const vtype2_yxx_ref < vtype > &v); + inline vtype3(const vtype2_yxy_ref < vtype > &v); + inline vtype3(const vtype2_yyx_ref < vtype > &v); + inline vtype3(const vtype2_yyy_ref < vtype > &v); + inline vtype3(const vtype3_xxx_ref < vtype > &v); + inline vtype3(const vtype3_xxy_ref < vtype > &v); + inline vtype3(const vtype3_xxz_ref < vtype > &v); + inline vtype3(const vtype3_xyx_ref < vtype > &v); + inline vtype3(const vtype3_xyy_ref < vtype > &v); + inline vtype3(const vtype3_xyz_ref < vtype > &v); + inline vtype3(const vtype3_xzx_ref < vtype > &v); + inline vtype3(const vtype3_xzy_ref < vtype > &v); + inline vtype3(const vtype3_xzz_ref < vtype > &v); + inline vtype3(const vtype3_yxx_ref < vtype > &v); + inline vtype3(const vtype3_yxy_ref < vtype > &v); + inline vtype3(const vtype3_yxz_ref < vtype > &v); + inline vtype3(const vtype3_yyx_ref < vtype > &v); + inline vtype3(const vtype3_yyy_ref < vtype > &v); + inline vtype3(const vtype3_yyz_ref < vtype > &v); + inline vtype3(const vtype3_yzx_ref < vtype > &v); + inline vtype3(const vtype3_yzy_ref < vtype > &v); + inline vtype3(const vtype3_yzz_ref < vtype > &v); + inline vtype3(const vtype3_zxx_ref < vtype > &v); + inline vtype3(const vtype3_zxy_ref < vtype > &v); + inline vtype3(const vtype3_zxz_ref < vtype > &v); + inline vtype3(const vtype3_zyx_ref < vtype > &v); + inline vtype3(const vtype3_zyy_ref < vtype > &v); + inline vtype3(const vtype3_zyz_ref < vtype > &v); + inline vtype3(const vtype3_zzx_ref < vtype > &v); + inline vtype3(const vtype3_zzy_ref < vtype > &v); + inline vtype3(const vtype3_zzz_ref < vtype > &v); + inline vtype3(const vtype4_xxx_ref < vtype > &v); + inline vtype3(const vtype4_xxy_ref < vtype > &v); + inline vtype3(const vtype4_xxz_ref < vtype > &v); + inline vtype3(const vtype4_xxw_ref < vtype > &v); + inline vtype3(const vtype4_xyx_ref < vtype > &v); + inline vtype3(const vtype4_xyy_ref < vtype > &v); + inline vtype3(const vtype4_xyz_ref < vtype > &v); + inline vtype3(const vtype4_xyw_ref < vtype > &v); + inline vtype3(const vtype4_xzx_ref < vtype > &v); + inline vtype3(const vtype4_xzy_ref < vtype > &v); + inline vtype3(const vtype4_xzz_ref < vtype > &v); + inline vtype3(const vtype4_xzw_ref < vtype > &v); + inline vtype3(const vtype4_xwx_ref < vtype > &v); + inline vtype3(const vtype4_xwy_ref < vtype > &v); + inline vtype3(const vtype4_xwz_ref < vtype > &v); + inline vtype3(const vtype4_xww_ref < vtype > &v); + inline vtype3(const vtype4_yxx_ref < vtype > &v); + inline vtype3(const vtype4_yxy_ref < vtype > &v); + inline vtype3(const vtype4_yxz_ref < vtype > &v); + inline vtype3(const vtype4_yxw_ref < vtype > &v); + inline vtype3(const vtype4_yyx_ref < vtype > &v); + inline vtype3(const vtype4_yyy_ref < vtype > &v); + inline vtype3(const vtype4_yyz_ref < vtype > &v); + inline vtype3(const vtype4_yyw_ref < vtype > &v); + inline vtype3(const vtype4_yzx_ref < vtype > &v); + inline vtype3(const vtype4_yzy_ref < vtype > &v); + inline vtype3(const vtype4_yzz_ref < vtype > &v); + inline vtype3(const vtype4_yzw_ref < vtype > &v); + inline vtype3(const vtype4_ywx_ref < vtype > &v); + inline vtype3(const vtype4_ywy_ref < vtype > &v); + inline vtype3(const vtype4_ywz_ref < vtype > &v); + inline vtype3(const vtype4_yww_ref < vtype > &v); + inline vtype3(const vtype4_zxx_ref < vtype > &v); + inline vtype3(const vtype4_zxy_ref < vtype > &v); + inline vtype3(const vtype4_zxz_ref < vtype > &v); + inline vtype3(const vtype4_zxw_ref < vtype > &v); + inline vtype3(const vtype4_zyx_ref < vtype > &v); + inline vtype3(const vtype4_zyy_ref < vtype > &v); + inline vtype3(const vtype4_zyz_ref < vtype > &v); + inline vtype3(const vtype4_zyw_ref < vtype > &v); + inline vtype3(const vtype4_zzx_ref < vtype > &v); + inline vtype3(const vtype4_zzy_ref < vtype > &v); + inline vtype3(const vtype4_zzz_ref < vtype > &v); + inline vtype3(const vtype4_zzw_ref < vtype > &v); + inline vtype3(const vtype4_zwx_ref < vtype > &v); + inline vtype3(const vtype4_zwy_ref < vtype > &v); + inline vtype3(const vtype4_zwz_ref < vtype > &v); + inline vtype3(const vtype4_zww_ref < vtype > &v); + inline vtype3(const vtype4_wxx_ref < vtype > &v); + inline vtype3(const vtype4_wxy_ref < vtype > &v); + inline vtype3(const vtype4_wxz_ref < vtype > &v); + inline vtype3(const vtype4_wxw_ref < vtype > &v); + inline vtype3(const vtype4_wyx_ref < vtype > &v); + inline vtype3(const vtype4_wyy_ref < vtype > &v); + inline vtype3(const vtype4_wyz_ref < vtype > &v); + inline vtype3(const vtype4_wyw_ref < vtype > &v); + inline vtype3(const vtype4_wzx_ref < vtype > &v); + inline vtype3(const vtype4_wzy_ref < vtype > &v); + inline vtype3(const vtype4_wzz_ref < vtype > &v); + inline vtype3(const vtype4_wzw_ref < vtype > &v); + inline vtype3(const vtype4_wwx_ref < vtype > &v); + inline vtype3(const vtype4_wwy_ref < vtype > &v); + inline vtype3(const vtype4_wwz_ref < vtype > &v); + inline vtype3(const vtype4_www_ref < vtype > &v); + vtype3_xx_ref < vtype > xx() + { + return vtype3_xx_ref < vtype > (this); + } + vtype3_xy_ref < vtype > xy() + { + return vtype3_xy_ref < vtype > (this); + } + vtype3_xz_ref < vtype > xz() + { + return vtype3_xz_ref < vtype > (this); + } + vtype3_yx_ref < vtype > yx() + { + return vtype3_yx_ref < vtype > (this); + } + vtype3_yy_ref < vtype > yy() + { + return vtype3_yy_ref < vtype > (this); + } + vtype3_yz_ref < vtype > yz() + { + return vtype3_yz_ref < vtype > (this); + } + vtype3_zx_ref < vtype > zx() + { + return vtype3_zx_ref < vtype > (this); + } + vtype3_zy_ref < vtype > zy() + { + return vtype3_zy_ref < vtype > (this); + } + vtype3_zz_ref < vtype > zz() + { + return vtype3_zz_ref < vtype > (this); + } + vtype3_xxx_ref < vtype > xxx() + { + return vtype3_xxx_ref < vtype > (this); + } + vtype3_xxy_ref < vtype > xxy() + { + return vtype3_xxy_ref < vtype > (this); + } + vtype3_xxz_ref < vtype > xxz() + { + return vtype3_xxz_ref < vtype > (this); + } + vtype3_xyx_ref < vtype > xyx() + { + return vtype3_xyx_ref < vtype > (this); + } + vtype3_xyy_ref < vtype > xyy() + { + return vtype3_xyy_ref < vtype > (this); + } + vtype3_xyz_ref < vtype > xyz() + { + return vtype3_xyz_ref < vtype > (this); + } + vtype3_xzx_ref < vtype > xzx() + { + return vtype3_xzx_ref < vtype > (this); + } + vtype3_xzy_ref < vtype > xzy() + { + return vtype3_xzy_ref < vtype > (this); + } + vtype3_xzz_ref < vtype > xzz() + { + return vtype3_xzz_ref < vtype > (this); + } + vtype3_yxx_ref < vtype > yxx() + { + return vtype3_yxx_ref < vtype > (this); + } + vtype3_yxy_ref < vtype > yxy() + { + return vtype3_yxy_ref < vtype > (this); + } + vtype3_yxz_ref < vtype > yxz() + { + return vtype3_yxz_ref < vtype > (this); + } + vtype3_yyx_ref < vtype > yyx() + { + return vtype3_yyx_ref < vtype > (this); + } + vtype3_yyy_ref < vtype > yyy() + { + return vtype3_yyy_ref < vtype > (this); + } + vtype3_yyz_ref < vtype > yyz() + { + return vtype3_yyz_ref < vtype > (this); + } + vtype3_yzx_ref < vtype > yzx() + { + return vtype3_yzx_ref < vtype > (this); + } + vtype3_yzy_ref < vtype > yzy() + { + return vtype3_yzy_ref < vtype > (this); + } + vtype3_yzz_ref < vtype > yzz() + { + return vtype3_yzz_ref < vtype > (this); + } + vtype3_zxx_ref < vtype > zxx() + { + return vtype3_zxx_ref < vtype > (this); + } + vtype3_zxy_ref < vtype > zxy() + { + return vtype3_zxy_ref < vtype > (this); + } + vtype3_zxz_ref < vtype > zxz() + { + return vtype3_zxz_ref < vtype > (this); + } + vtype3_zyx_ref < vtype > zyx() + { + return vtype3_zyx_ref < vtype > (this); + } + vtype3_zyy_ref < vtype > zyy() + { + return vtype3_zyy_ref < vtype > (this); + } + vtype3_zyz_ref < vtype > zyz() + { + return vtype3_zyz_ref < vtype > (this); + } + vtype3_zzx_ref < vtype > zzx() + { + return vtype3_zzx_ref < vtype > (this); + } + vtype3_zzy_ref < vtype > zzy() + { + return vtype3_zzy_ref < vtype > (this); + } + vtype3_zzz_ref < vtype > zzz() + { + return vtype3_zzz_ref < vtype > (this); + } + vtype3_xxxx_ref < vtype > xxxx() + { + return vtype3_xxxx_ref < vtype > (this); + } + vtype3_xxxy_ref < vtype > xxxy() + { + return vtype3_xxxy_ref < vtype > (this); + } + vtype3_xxxz_ref < vtype > xxxz() + { + return vtype3_xxxz_ref < vtype > (this); + } + vtype3_xxyx_ref < vtype > xxyx() + { + return vtype3_xxyx_ref < vtype > (this); + } + vtype3_xxyy_ref < vtype > xxyy() + { + return vtype3_xxyy_ref < vtype > (this); + } + vtype3_xxyz_ref < vtype > xxyz() + { + return vtype3_xxyz_ref < vtype > (this); + } + vtype3_xxzx_ref < vtype > xxzx() + { + return vtype3_xxzx_ref < vtype > (this); + } + vtype3_xxzy_ref < vtype > xxzy() + { + return vtype3_xxzy_ref < vtype > (this); + } + vtype3_xxzz_ref < vtype > xxzz() + { + return vtype3_xxzz_ref < vtype > (this); + } + vtype3_xyxx_ref < vtype > xyxx() + { + return vtype3_xyxx_ref < vtype > (this); + } + vtype3_xyxy_ref < vtype > xyxy() + { + return vtype3_xyxy_ref < vtype > (this); + } + vtype3_xyxz_ref < vtype > xyxz() + { + return vtype3_xyxz_ref < vtype > (this); + } + vtype3_xyyx_ref < vtype > xyyx() + { + return vtype3_xyyx_ref < vtype > (this); + } + vtype3_xyyy_ref < vtype > xyyy() + { + return vtype3_xyyy_ref < vtype > (this); + } + vtype3_xyyz_ref < vtype > xyyz() + { + return vtype3_xyyz_ref < vtype > (this); + } + vtype3_xyzx_ref < vtype > xyzx() + { + return vtype3_xyzx_ref < vtype > (this); + } + vtype3_xyzy_ref < vtype > xyzy() + { + return vtype3_xyzy_ref < vtype > (this); + } + vtype3_xyzz_ref < vtype > xyzz() + { + return vtype3_xyzz_ref < vtype > (this); + } + vtype3_xzxx_ref < vtype > xzxx() + { + return vtype3_xzxx_ref < vtype > (this); + } + vtype3_xzxy_ref < vtype > xzxy() + { + return vtype3_xzxy_ref < vtype > (this); + } + vtype3_xzxz_ref < vtype > xzxz() + { + return vtype3_xzxz_ref < vtype > (this); + } + vtype3_xzyx_ref < vtype > xzyx() + { + return vtype3_xzyx_ref < vtype > (this); + } + vtype3_xzyy_ref < vtype > xzyy() + { + return vtype3_xzyy_ref < vtype > (this); + } + vtype3_xzyz_ref < vtype > xzyz() + { + return vtype3_xzyz_ref < vtype > (this); + } + vtype3_xzzx_ref < vtype > xzzx() + { + return vtype3_xzzx_ref < vtype > (this); + } + vtype3_xzzy_ref < vtype > xzzy() + { + return vtype3_xzzy_ref < vtype > (this); + } + vtype3_xzzz_ref < vtype > xzzz() + { + return vtype3_xzzz_ref < vtype > (this); + } + vtype3_yxxx_ref < vtype > yxxx() + { + return vtype3_yxxx_ref < vtype > (this); + } + vtype3_yxxy_ref < vtype > yxxy() + { + return vtype3_yxxy_ref < vtype > (this); + } + vtype3_yxxz_ref < vtype > yxxz() + { + return vtype3_yxxz_ref < vtype > (this); + } + vtype3_yxyx_ref < vtype > yxyx() + { + return vtype3_yxyx_ref < vtype > (this); + } + vtype3_yxyy_ref < vtype > yxyy() + { + return vtype3_yxyy_ref < vtype > (this); + } + vtype3_yxyz_ref < vtype > yxyz() + { + return vtype3_yxyz_ref < vtype > (this); + } + vtype3_yxzx_ref < vtype > yxzx() + { + return vtype3_yxzx_ref < vtype > (this); + } + vtype3_yxzy_ref < vtype > yxzy() + { + return vtype3_yxzy_ref < vtype > (this); + } + vtype3_yxzz_ref < vtype > yxzz() + { + return vtype3_yxzz_ref < vtype > (this); + } + vtype3_yyxx_ref < vtype > yyxx() + { + return vtype3_yyxx_ref < vtype > (this); + } + vtype3_yyxy_ref < vtype > yyxy() + { + return vtype3_yyxy_ref < vtype > (this); + } + vtype3_yyxz_ref < vtype > yyxz() + { + return vtype3_yyxz_ref < vtype > (this); + } + vtype3_yyyx_ref < vtype > yyyx() + { + return vtype3_yyyx_ref < vtype > (this); + } + vtype3_yyyy_ref < vtype > yyyy() + { + return vtype3_yyyy_ref < vtype > (this); + } + vtype3_yyyz_ref < vtype > yyyz() + { + return vtype3_yyyz_ref < vtype > (this); + } + vtype3_yyzx_ref < vtype > yyzx() + { + return vtype3_yyzx_ref < vtype > (this); + } + vtype3_yyzy_ref < vtype > yyzy() + { + return vtype3_yyzy_ref < vtype > (this); + } + vtype3_yyzz_ref < vtype > yyzz() + { + return vtype3_yyzz_ref < vtype > (this); + } + vtype3_yzxx_ref < vtype > yzxx() + { + return vtype3_yzxx_ref < vtype > (this); + } + vtype3_yzxy_ref < vtype > yzxy() + { + return vtype3_yzxy_ref < vtype > (this); + } + vtype3_yzxz_ref < vtype > yzxz() + { + return vtype3_yzxz_ref < vtype > (this); + } + vtype3_yzyx_ref < vtype > yzyx() + { + return vtype3_yzyx_ref < vtype > (this); + } + vtype3_yzyy_ref < vtype > yzyy() + { + return vtype3_yzyy_ref < vtype > (this); + } + vtype3_yzyz_ref < vtype > yzyz() + { + return vtype3_yzyz_ref < vtype > (this); + } + vtype3_yzzx_ref < vtype > yzzx() + { + return vtype3_yzzx_ref < vtype > (this); + } + vtype3_yzzy_ref < vtype > yzzy() + { + return vtype3_yzzy_ref < vtype > (this); + } + vtype3_yzzz_ref < vtype > yzzz() + { + return vtype3_yzzz_ref < vtype > (this); + } + vtype3_zxxx_ref < vtype > zxxx() + { + return vtype3_zxxx_ref < vtype > (this); + } + vtype3_zxxy_ref < vtype > zxxy() + { + return vtype3_zxxy_ref < vtype > (this); + } + vtype3_zxxz_ref < vtype > zxxz() + { + return vtype3_zxxz_ref < vtype > (this); + } + vtype3_zxyx_ref < vtype > zxyx() + { + return vtype3_zxyx_ref < vtype > (this); + } + vtype3_zxyy_ref < vtype > zxyy() + { + return vtype3_zxyy_ref < vtype > (this); + } + vtype3_zxyz_ref < vtype > zxyz() + { + return vtype3_zxyz_ref < vtype > (this); + } + vtype3_zxzx_ref < vtype > zxzx() + { + return vtype3_zxzx_ref < vtype > (this); + } + vtype3_zxzy_ref < vtype > zxzy() + { + return vtype3_zxzy_ref < vtype > (this); + } + vtype3_zxzz_ref < vtype > zxzz() + { + return vtype3_zxzz_ref < vtype > (this); + } + vtype3_zyxx_ref < vtype > zyxx() + { + return vtype3_zyxx_ref < vtype > (this); + } + vtype3_zyxy_ref < vtype > zyxy() + { + return vtype3_zyxy_ref < vtype > (this); + } + vtype3_zyxz_ref < vtype > zyxz() + { + return vtype3_zyxz_ref < vtype > (this); + } + vtype3_zyyx_ref < vtype > zyyx() + { + return vtype3_zyyx_ref < vtype > (this); + } + vtype3_zyyy_ref < vtype > zyyy() + { + return vtype3_zyyy_ref < vtype > (this); + } + vtype3_zyyz_ref < vtype > zyyz() + { + return vtype3_zyyz_ref < vtype > (this); + } + vtype3_zyzx_ref < vtype > zyzx() + { + return vtype3_zyzx_ref < vtype > (this); + } + vtype3_zyzy_ref < vtype > zyzy() + { + return vtype3_zyzy_ref < vtype > (this); + } + vtype3_zyzz_ref < vtype > zyzz() + { + return vtype3_zyzz_ref < vtype > (this); + } + vtype3_zzxx_ref < vtype > zzxx() + { + return vtype3_zzxx_ref < vtype > (this); + } + vtype3_zzxy_ref < vtype > zzxy() + { + return vtype3_zzxy_ref < vtype > (this); + } + vtype3_zzxz_ref < vtype > zzxz() + { + return vtype3_zzxz_ref < vtype > (this); + } + vtype3_zzyx_ref < vtype > zzyx() + { + return vtype3_zzyx_ref < vtype > (this); + } + vtype3_zzyy_ref < vtype > zzyy() + { + return vtype3_zzyy_ref < vtype > (this); + } + vtype3_zzyz_ref < vtype > zzyz() + { + return vtype3_zzyz_ref < vtype > (this); + } + vtype3_zzzx_ref < vtype > zzzx() + { + return vtype3_zzzx_ref < vtype > (this); + } + vtype3_zzzy_ref < vtype > zzzy() + { + return vtype3_zzzy_ref < vtype > (this); + } + vtype3_zzzz_ref < vtype > zzzz() + { + return vtype3_zzzz_ref < vtype > (this); + } +}; + +template < typename vtype > class vtype4 +{ + public: + vtype x, y, z, w; + vtype4() + { + }; + vtype4(vtype p, vtype q, vtype r, vtype s):x(p), y(q), z(r), w(s) + { + }; + vtype4(const vtype2 < vtype > &p, const vtype2 < vtype > &q):x(p.x), y(p.y), z(q.x), w(q.y) + { + }; + vtype4(const vtype2 < vtype > &p, vtype q, vtype r):x(p.x), y(p.y), z(q), w(r) + { + }; + vtype4(vtype p, const vtype2 < vtype > &q, vtype r):x(p), y(q.x), z(q.y), w(r) + { + }; + vtype4(vtype p, vtype q, const vtype2 < vtype > &r):x(p), y(q), z(r.x), w(r.y) + { + }; + vtype4(const vtype3 < vtype > &p, vtype q):x(p.x), y(p.y), z(p.z), w(q) + { + }; + vtype4(vtype p, const vtype3 < vtype > &q):x(p), y(q.x), z(q.y), w(q.z) + { + }; + vtype4(const vtype4 & p):x(p.x), y(p.y), z(p.z), w(p.w) + { + }; + inline vtype4(const vtype2_xxxx_ref < vtype > &v); + inline vtype4(const vtype2_xxxy_ref < vtype > &v); + inline vtype4(const vtype2_xxyx_ref < vtype > &v); + inline vtype4(const vtype2_xxyy_ref < vtype > &v); + inline vtype4(const vtype2_xyxx_ref < vtype > &v); + inline vtype4(const vtype2_xyxy_ref < vtype > &v); + inline vtype4(const vtype2_xyyx_ref < vtype > &v); + inline vtype4(const vtype2_xyyy_ref < vtype > &v); + inline vtype4(const vtype2_yxxx_ref < vtype > &v); + inline vtype4(const vtype2_yxxy_ref < vtype > &v); + inline vtype4(const vtype2_yxyx_ref < vtype > &v); + inline vtype4(const vtype2_yxyy_ref < vtype > &v); + inline vtype4(const vtype2_yyxx_ref < vtype > &v); + inline vtype4(const vtype2_yyxy_ref < vtype > &v); + inline vtype4(const vtype2_yyyx_ref < vtype > &v); + inline vtype4(const vtype2_yyyy_ref < vtype > &v); + inline vtype4(const vtype3_xxxx_ref < vtype > &v); + inline vtype4(const vtype3_xxxy_ref < vtype > &v); + inline vtype4(const vtype3_xxxz_ref < vtype > &v); + inline vtype4(const vtype3_xxyx_ref < vtype > &v); + inline vtype4(const vtype3_xxyy_ref < vtype > &v); + inline vtype4(const vtype3_xxyz_ref < vtype > &v); + inline vtype4(const vtype3_xxzx_ref < vtype > &v); + inline vtype4(const vtype3_xxzy_ref < vtype > &v); + inline vtype4(const vtype3_xxzz_ref < vtype > &v); + inline vtype4(const vtype3_xyxx_ref < vtype > &v); + inline vtype4(const vtype3_xyxy_ref < vtype > &v); + inline vtype4(const vtype3_xyxz_ref < vtype > &v); + inline vtype4(const vtype3_xyyx_ref < vtype > &v); + inline vtype4(const vtype3_xyyy_ref < vtype > &v); + inline vtype4(const vtype3_xyyz_ref < vtype > &v); + inline vtype4(const vtype3_xyzx_ref < vtype > &v); + inline vtype4(const vtype3_xyzy_ref < vtype > &v); + inline vtype4(const vtype3_xyzz_ref < vtype > &v); + inline vtype4(const vtype3_xzxx_ref < vtype > &v); + inline vtype4(const vtype3_xzxy_ref < vtype > &v); + inline vtype4(const vtype3_xzxz_ref < vtype > &v); + inline vtype4(const vtype3_xzyx_ref < vtype > &v); + inline vtype4(const vtype3_xzyy_ref < vtype > &v); + inline vtype4(const vtype3_xzyz_ref < vtype > &v); + inline vtype4(const vtype3_xzzx_ref < vtype > &v); + inline vtype4(const vtype3_xzzy_ref < vtype > &v); + inline vtype4(const vtype3_xzzz_ref < vtype > &v); + inline vtype4(const vtype3_yxxx_ref < vtype > &v); + inline vtype4(const vtype3_yxxy_ref < vtype > &v); + inline vtype4(const vtype3_yxxz_ref < vtype > &v); + inline vtype4(const vtype3_yxyx_ref < vtype > &v); + inline vtype4(const vtype3_yxyy_ref < vtype > &v); + inline vtype4(const vtype3_yxyz_ref < vtype > &v); + inline vtype4(const vtype3_yxzx_ref < vtype > &v); + inline vtype4(const vtype3_yxzy_ref < vtype > &v); + inline vtype4(const vtype3_yxzz_ref < vtype > &v); + inline vtype4(const vtype3_yyxx_ref < vtype > &v); + inline vtype4(const vtype3_yyxy_ref < vtype > &v); + inline vtype4(const vtype3_yyxz_ref < vtype > &v); + inline vtype4(const vtype3_yyyx_ref < vtype > &v); + inline vtype4(const vtype3_yyyy_ref < vtype > &v); + inline vtype4(const vtype3_yyyz_ref < vtype > &v); + inline vtype4(const vtype3_yyzx_ref < vtype > &v); + inline vtype4(const vtype3_yyzy_ref < vtype > &v); + inline vtype4(const vtype3_yyzz_ref < vtype > &v); + inline vtype4(const vtype3_yzxx_ref < vtype > &v); + inline vtype4(const vtype3_yzxy_ref < vtype > &v); + inline vtype4(const vtype3_yzxz_ref < vtype > &v); + inline vtype4(const vtype3_yzyx_ref < vtype > &v); + inline vtype4(const vtype3_yzyy_ref < vtype > &v); + inline vtype4(const vtype3_yzyz_ref < vtype > &v); + inline vtype4(const vtype3_yzzx_ref < vtype > &v); + inline vtype4(const vtype3_yzzy_ref < vtype > &v); + inline vtype4(const vtype3_yzzz_ref < vtype > &v); + inline vtype4(const vtype3_zxxx_ref < vtype > &v); + inline vtype4(const vtype3_zxxy_ref < vtype > &v); + inline vtype4(const vtype3_zxxz_ref < vtype > &v); + inline vtype4(const vtype3_zxyx_ref < vtype > &v); + inline vtype4(const vtype3_zxyy_ref < vtype > &v); + inline vtype4(const vtype3_zxyz_ref < vtype > &v); + inline vtype4(const vtype3_zxzx_ref < vtype > &v); + inline vtype4(const vtype3_zxzy_ref < vtype > &v); + inline vtype4(const vtype3_zxzz_ref < vtype > &v); + inline vtype4(const vtype3_zyxx_ref < vtype > &v); + inline vtype4(const vtype3_zyxy_ref < vtype > &v); + inline vtype4(const vtype3_zyxz_ref < vtype > &v); + inline vtype4(const vtype3_zyyx_ref < vtype > &v); + inline vtype4(const vtype3_zyyy_ref < vtype > &v); + inline vtype4(const vtype3_zyyz_ref < vtype > &v); + inline vtype4(const vtype3_zyzx_ref < vtype > &v); + inline vtype4(const vtype3_zyzy_ref < vtype > &v); + inline vtype4(const vtype3_zyzz_ref < vtype > &v); + inline vtype4(const vtype3_zzxx_ref < vtype > &v); + inline vtype4(const vtype3_zzxy_ref < vtype > &v); + inline vtype4(const vtype3_zzxz_ref < vtype > &v); + inline vtype4(const vtype3_zzyx_ref < vtype > &v); + inline vtype4(const vtype3_zzyy_ref < vtype > &v); + inline vtype4(const vtype3_zzyz_ref < vtype > &v); + inline vtype4(const vtype3_zzzx_ref < vtype > &v); + inline vtype4(const vtype3_zzzy_ref < vtype > &v); + inline vtype4(const vtype3_zzzz_ref < vtype > &v); + inline vtype4(const vtype4_xxxx_ref < vtype > &v); + inline vtype4(const vtype4_xxxy_ref < vtype > &v); + inline vtype4(const vtype4_xxxz_ref < vtype > &v); + inline vtype4(const vtype4_xxxw_ref < vtype > &v); + inline vtype4(const vtype4_xxyx_ref < vtype > &v); + inline vtype4(const vtype4_xxyy_ref < vtype > &v); + inline vtype4(const vtype4_xxyz_ref < vtype > &v); + inline vtype4(const vtype4_xxyw_ref < vtype > &v); + inline vtype4(const vtype4_xxzx_ref < vtype > &v); + inline vtype4(const vtype4_xxzy_ref < vtype > &v); + inline vtype4(const vtype4_xxzz_ref < vtype > &v); + inline vtype4(const vtype4_xxzw_ref < vtype > &v); + inline vtype4(const vtype4_xxwx_ref < vtype > &v); + inline vtype4(const vtype4_xxwy_ref < vtype > &v); + inline vtype4(const vtype4_xxwz_ref < vtype > &v); + inline vtype4(const vtype4_xxww_ref < vtype > &v); + inline vtype4(const vtype4_xyxx_ref < vtype > &v); + inline vtype4(const vtype4_xyxy_ref < vtype > &v); + inline vtype4(const vtype4_xyxz_ref < vtype > &v); + inline vtype4(const vtype4_xyxw_ref < vtype > &v); + inline vtype4(const vtype4_xyyx_ref < vtype > &v); + inline vtype4(const vtype4_xyyy_ref < vtype > &v); + inline vtype4(const vtype4_xyyz_ref < vtype > &v); + inline vtype4(const vtype4_xyyw_ref < vtype > &v); + inline vtype4(const vtype4_xyzx_ref < vtype > &v); + inline vtype4(const vtype4_xyzy_ref < vtype > &v); + inline vtype4(const vtype4_xyzz_ref < vtype > &v); + inline vtype4(const vtype4_xyzw_ref < vtype > &v); + inline vtype4(const vtype4_xywx_ref < vtype > &v); + inline vtype4(const vtype4_xywy_ref < vtype > &v); + inline vtype4(const vtype4_xywz_ref < vtype > &v); + inline vtype4(const vtype4_xyww_ref < vtype > &v); + inline vtype4(const vtype4_xzxx_ref < vtype > &v); + inline vtype4(const vtype4_xzxy_ref < vtype > &v); + inline vtype4(const vtype4_xzxz_ref < vtype > &v); + inline vtype4(const vtype4_xzxw_ref < vtype > &v); + inline vtype4(const vtype4_xzyx_ref < vtype > &v); + inline vtype4(const vtype4_xzyy_ref < vtype > &v); + inline vtype4(const vtype4_xzyz_ref < vtype > &v); + inline vtype4(const vtype4_xzyw_ref < vtype > &v); + inline vtype4(const vtype4_xzzx_ref < vtype > &v); + inline vtype4(const vtype4_xzzy_ref < vtype > &v); + inline vtype4(const vtype4_xzzz_ref < vtype > &v); + inline vtype4(const vtype4_xzzw_ref < vtype > &v); + inline vtype4(const vtype4_xzwx_ref < vtype > &v); + inline vtype4(const vtype4_xzwy_ref < vtype > &v); + inline vtype4(const vtype4_xzwz_ref < vtype > &v); + inline vtype4(const vtype4_xzww_ref < vtype > &v); + inline vtype4(const vtype4_xwxx_ref < vtype > &v); + inline vtype4(const vtype4_xwxy_ref < vtype > &v); + inline vtype4(const vtype4_xwxz_ref < vtype > &v); + inline vtype4(const vtype4_xwxw_ref < vtype > &v); + inline vtype4(const vtype4_xwyx_ref < vtype > &v); + inline vtype4(const vtype4_xwyy_ref < vtype > &v); + inline vtype4(const vtype4_xwyz_ref < vtype > &v); + inline vtype4(const vtype4_xwyw_ref < vtype > &v); + inline vtype4(const vtype4_xwzx_ref < vtype > &v); + inline vtype4(const vtype4_xwzy_ref < vtype > &v); + inline vtype4(const vtype4_xwzz_ref < vtype > &v); + inline vtype4(const vtype4_xwzw_ref < vtype > &v); + inline vtype4(const vtype4_xwwx_ref < vtype > &v); + inline vtype4(const vtype4_xwwy_ref < vtype > &v); + inline vtype4(const vtype4_xwwz_ref < vtype > &v); + inline vtype4(const vtype4_xwww_ref < vtype > &v); + inline vtype4(const vtype4_yxxx_ref < vtype > &v); + inline vtype4(const vtype4_yxxy_ref < vtype > &v); + inline vtype4(const vtype4_yxxz_ref < vtype > &v); + inline vtype4(const vtype4_yxxw_ref < vtype > &v); + inline vtype4(const vtype4_yxyx_ref < vtype > &v); + inline vtype4(const vtype4_yxyy_ref < vtype > &v); + inline vtype4(const vtype4_yxyz_ref < vtype > &v); + inline vtype4(const vtype4_yxyw_ref < vtype > &v); + inline vtype4(const vtype4_yxzx_ref < vtype > &v); + inline vtype4(const vtype4_yxzy_ref < vtype > &v); + inline vtype4(const vtype4_yxzz_ref < vtype > &v); + inline vtype4(const vtype4_yxzw_ref < vtype > &v); + inline vtype4(const vtype4_yxwx_ref < vtype > &v); + inline vtype4(const vtype4_yxwy_ref < vtype > &v); + inline vtype4(const vtype4_yxwz_ref < vtype > &v); + inline vtype4(const vtype4_yxww_ref < vtype > &v); + inline vtype4(const vtype4_yyxx_ref < vtype > &v); + inline vtype4(const vtype4_yyxy_ref < vtype > &v); + inline vtype4(const vtype4_yyxz_ref < vtype > &v); + inline vtype4(const vtype4_yyxw_ref < vtype > &v); + inline vtype4(const vtype4_yyyx_ref < vtype > &v); + inline vtype4(const vtype4_yyyy_ref < vtype > &v); + inline vtype4(const vtype4_yyyz_ref < vtype > &v); + inline vtype4(const vtype4_yyyw_ref < vtype > &v); + inline vtype4(const vtype4_yyzx_ref < vtype > &v); + inline vtype4(const vtype4_yyzy_ref < vtype > &v); + inline vtype4(const vtype4_yyzz_ref < vtype > &v); + inline vtype4(const vtype4_yyzw_ref < vtype > &v); + inline vtype4(const vtype4_yywx_ref < vtype > &v); + inline vtype4(const vtype4_yywy_ref < vtype > &v); + inline vtype4(const vtype4_yywz_ref < vtype > &v); + inline vtype4(const vtype4_yyww_ref < vtype > &v); + inline vtype4(const vtype4_yzxx_ref < vtype > &v); + inline vtype4(const vtype4_yzxy_ref < vtype > &v); + inline vtype4(const vtype4_yzxz_ref < vtype > &v); + inline vtype4(const vtype4_yzxw_ref < vtype > &v); + inline vtype4(const vtype4_yzyx_ref < vtype > &v); + inline vtype4(const vtype4_yzyy_ref < vtype > &v); + inline vtype4(const vtype4_yzyz_ref < vtype > &v); + inline vtype4(const vtype4_yzyw_ref < vtype > &v); + inline vtype4(const vtype4_yzzx_ref < vtype > &v); + inline vtype4(const vtype4_yzzy_ref < vtype > &v); + inline vtype4(const vtype4_yzzz_ref < vtype > &v); + inline vtype4(const vtype4_yzzw_ref < vtype > &v); + inline vtype4(const vtype4_yzwx_ref < vtype > &v); + inline vtype4(const vtype4_yzwy_ref < vtype > &v); + inline vtype4(const vtype4_yzwz_ref < vtype > &v); + inline vtype4(const vtype4_yzww_ref < vtype > &v); + inline vtype4(const vtype4_ywxx_ref < vtype > &v); + inline vtype4(const vtype4_ywxy_ref < vtype > &v); + inline vtype4(const vtype4_ywxz_ref < vtype > &v); + inline vtype4(const vtype4_ywxw_ref < vtype > &v); + inline vtype4(const vtype4_ywyx_ref < vtype > &v); + inline vtype4(const vtype4_ywyy_ref < vtype > &v); + inline vtype4(const vtype4_ywyz_ref < vtype > &v); + inline vtype4(const vtype4_ywyw_ref < vtype > &v); + inline vtype4(const vtype4_ywzx_ref < vtype > &v); + inline vtype4(const vtype4_ywzy_ref < vtype > &v); + inline vtype4(const vtype4_ywzz_ref < vtype > &v); + inline vtype4(const vtype4_ywzw_ref < vtype > &v); + inline vtype4(const vtype4_ywwx_ref < vtype > &v); + inline vtype4(const vtype4_ywwy_ref < vtype > &v); + inline vtype4(const vtype4_ywwz_ref < vtype > &v); + inline vtype4(const vtype4_ywww_ref < vtype > &v); + inline vtype4(const vtype4_zxxx_ref < vtype > &v); + inline vtype4(const vtype4_zxxy_ref < vtype > &v); + inline vtype4(const vtype4_zxxz_ref < vtype > &v); + inline vtype4(const vtype4_zxxw_ref < vtype > &v); + inline vtype4(const vtype4_zxyx_ref < vtype > &v); + inline vtype4(const vtype4_zxyy_ref < vtype > &v); + inline vtype4(const vtype4_zxyz_ref < vtype > &v); + inline vtype4(const vtype4_zxyw_ref < vtype > &v); + inline vtype4(const vtype4_zxzx_ref < vtype > &v); + inline vtype4(const vtype4_zxzy_ref < vtype > &v); + inline vtype4(const vtype4_zxzz_ref < vtype > &v); + inline vtype4(const vtype4_zxzw_ref < vtype > &v); + inline vtype4(const vtype4_zxwx_ref < vtype > &v); + inline vtype4(const vtype4_zxwy_ref < vtype > &v); + inline vtype4(const vtype4_zxwz_ref < vtype > &v); + inline vtype4(const vtype4_zxww_ref < vtype > &v); + inline vtype4(const vtype4_zyxx_ref < vtype > &v); + inline vtype4(const vtype4_zyxy_ref < vtype > &v); + inline vtype4(const vtype4_zyxz_ref < vtype > &v); + inline vtype4(const vtype4_zyxw_ref < vtype > &v); + inline vtype4(const vtype4_zyyx_ref < vtype > &v); + inline vtype4(const vtype4_zyyy_ref < vtype > &v); + inline vtype4(const vtype4_zyyz_ref < vtype > &v); + inline vtype4(const vtype4_zyyw_ref < vtype > &v); + inline vtype4(const vtype4_zyzx_ref < vtype > &v); + inline vtype4(const vtype4_zyzy_ref < vtype > &v); + inline vtype4(const vtype4_zyzz_ref < vtype > &v); + inline vtype4(const vtype4_zyzw_ref < vtype > &v); + inline vtype4(const vtype4_zywx_ref < vtype > &v); + inline vtype4(const vtype4_zywy_ref < vtype > &v); + inline vtype4(const vtype4_zywz_ref < vtype > &v); + inline vtype4(const vtype4_zyww_ref < vtype > &v); + inline vtype4(const vtype4_zzxx_ref < vtype > &v); + inline vtype4(const vtype4_zzxy_ref < vtype > &v); + inline vtype4(const vtype4_zzxz_ref < vtype > &v); + inline vtype4(const vtype4_zzxw_ref < vtype > &v); + inline vtype4(const vtype4_zzyx_ref < vtype > &v); + inline vtype4(const vtype4_zzyy_ref < vtype > &v); + inline vtype4(const vtype4_zzyz_ref < vtype > &v); + inline vtype4(const vtype4_zzyw_ref < vtype > &v); + inline vtype4(const vtype4_zzzx_ref < vtype > &v); + inline vtype4(const vtype4_zzzy_ref < vtype > &v); + inline vtype4(const vtype4_zzzz_ref < vtype > &v); + inline vtype4(const vtype4_zzzw_ref < vtype > &v); + inline vtype4(const vtype4_zzwx_ref < vtype > &v); + inline vtype4(const vtype4_zzwy_ref < vtype > &v); + inline vtype4(const vtype4_zzwz_ref < vtype > &v); + inline vtype4(const vtype4_zzww_ref < vtype > &v); + inline vtype4(const vtype4_zwxx_ref < vtype > &v); + inline vtype4(const vtype4_zwxy_ref < vtype > &v); + inline vtype4(const vtype4_zwxz_ref < vtype > &v); + inline vtype4(const vtype4_zwxw_ref < vtype > &v); + inline vtype4(const vtype4_zwyx_ref < vtype > &v); + inline vtype4(const vtype4_zwyy_ref < vtype > &v); + inline vtype4(const vtype4_zwyz_ref < vtype > &v); + inline vtype4(const vtype4_zwyw_ref < vtype > &v); + inline vtype4(const vtype4_zwzx_ref < vtype > &v); + inline vtype4(const vtype4_zwzy_ref < vtype > &v); + inline vtype4(const vtype4_zwzz_ref < vtype > &v); + inline vtype4(const vtype4_zwzw_ref < vtype > &v); + inline vtype4(const vtype4_zwwx_ref < vtype > &v); + inline vtype4(const vtype4_zwwy_ref < vtype > &v); + inline vtype4(const vtype4_zwwz_ref < vtype > &v); + inline vtype4(const vtype4_zwww_ref < vtype > &v); + inline vtype4(const vtype4_wxxx_ref < vtype > &v); + inline vtype4(const vtype4_wxxy_ref < vtype > &v); + inline vtype4(const vtype4_wxxz_ref < vtype > &v); + inline vtype4(const vtype4_wxxw_ref < vtype > &v); + inline vtype4(const vtype4_wxyx_ref < vtype > &v); + inline vtype4(const vtype4_wxyy_ref < vtype > &v); + inline vtype4(const vtype4_wxyz_ref < vtype > &v); + inline vtype4(const vtype4_wxyw_ref < vtype > &v); + inline vtype4(const vtype4_wxzx_ref < vtype > &v); + inline vtype4(const vtype4_wxzy_ref < vtype > &v); + inline vtype4(const vtype4_wxzz_ref < vtype > &v); + inline vtype4(const vtype4_wxzw_ref < vtype > &v); + inline vtype4(const vtype4_wxwx_ref < vtype > &v); + inline vtype4(const vtype4_wxwy_ref < vtype > &v); + inline vtype4(const vtype4_wxwz_ref < vtype > &v); + inline vtype4(const vtype4_wxww_ref < vtype > &v); + inline vtype4(const vtype4_wyxx_ref < vtype > &v); + inline vtype4(const vtype4_wyxy_ref < vtype > &v); + inline vtype4(const vtype4_wyxz_ref < vtype > &v); + inline vtype4(const vtype4_wyxw_ref < vtype > &v); + inline vtype4(const vtype4_wyyx_ref < vtype > &v); + inline vtype4(const vtype4_wyyy_ref < vtype > &v); + inline vtype4(const vtype4_wyyz_ref < vtype > &v); + inline vtype4(const vtype4_wyyw_ref < vtype > &v); + inline vtype4(const vtype4_wyzx_ref < vtype > &v); + inline vtype4(const vtype4_wyzy_ref < vtype > &v); + inline vtype4(const vtype4_wyzz_ref < vtype > &v); + inline vtype4(const vtype4_wyzw_ref < vtype > &v); + inline vtype4(const vtype4_wywx_ref < vtype > &v); + inline vtype4(const vtype4_wywy_ref < vtype > &v); + inline vtype4(const vtype4_wywz_ref < vtype > &v); + inline vtype4(const vtype4_wyww_ref < vtype > &v); + inline vtype4(const vtype4_wzxx_ref < vtype > &v); + inline vtype4(const vtype4_wzxy_ref < vtype > &v); + inline vtype4(const vtype4_wzxz_ref < vtype > &v); + inline vtype4(const vtype4_wzxw_ref < vtype > &v); + inline vtype4(const vtype4_wzyx_ref < vtype > &v); + inline vtype4(const vtype4_wzyy_ref < vtype > &v); + inline vtype4(const vtype4_wzyz_ref < vtype > &v); + inline vtype4(const vtype4_wzyw_ref < vtype > &v); + inline vtype4(const vtype4_wzzx_ref < vtype > &v); + inline vtype4(const vtype4_wzzy_ref < vtype > &v); + inline vtype4(const vtype4_wzzz_ref < vtype > &v); + inline vtype4(const vtype4_wzzw_ref < vtype > &v); + inline vtype4(const vtype4_wzwx_ref < vtype > &v); + inline vtype4(const vtype4_wzwy_ref < vtype > &v); + inline vtype4(const vtype4_wzwz_ref < vtype > &v); + inline vtype4(const vtype4_wzww_ref < vtype > &v); + inline vtype4(const vtype4_wwxx_ref < vtype > &v); + inline vtype4(const vtype4_wwxy_ref < vtype > &v); + inline vtype4(const vtype4_wwxz_ref < vtype > &v); + inline vtype4(const vtype4_wwxw_ref < vtype > &v); + inline vtype4(const vtype4_wwyx_ref < vtype > &v); + inline vtype4(const vtype4_wwyy_ref < vtype > &v); + inline vtype4(const vtype4_wwyz_ref < vtype > &v); + inline vtype4(const vtype4_wwyw_ref < vtype > &v); + inline vtype4(const vtype4_wwzx_ref < vtype > &v); + inline vtype4(const vtype4_wwzy_ref < vtype > &v); + inline vtype4(const vtype4_wwzz_ref < vtype > &v); + inline vtype4(const vtype4_wwzw_ref < vtype > &v); + inline vtype4(const vtype4_wwwx_ref < vtype > &v); + inline vtype4(const vtype4_wwwy_ref < vtype > &v); + inline vtype4(const vtype4_wwwz_ref < vtype > &v); + inline vtype4(const vtype4_wwww_ref < vtype > &v); + vtype4_xx_ref < vtype > xx() + { + return vtype4_xx_ref < vtype > (this); + } + vtype4_xy_ref < vtype > xy() + { + return vtype4_xy_ref < vtype > (this); + } + vtype4_xz_ref < vtype > xz() + { + return vtype4_xz_ref < vtype > (this); + } + vtype4_xw_ref < vtype > xw() + { + return vtype4_xw_ref < vtype > (this); + } + vtype4_yx_ref < vtype > yx() + { + return vtype4_yx_ref < vtype > (this); + } + vtype4_yy_ref < vtype > yy() + { + return vtype4_yy_ref < vtype > (this); + } + vtype4_yz_ref < vtype > yz() + { + return vtype4_yz_ref < vtype > (this); + } + vtype4_yw_ref < vtype > yw() + { + return vtype4_yw_ref < vtype > (this); + } + vtype4_zx_ref < vtype > zx() + { + return vtype4_zx_ref < vtype > (this); + } + vtype4_zy_ref < vtype > zy() + { + return vtype4_zy_ref < vtype > (this); + } + vtype4_zz_ref < vtype > zz() + { + return vtype4_zz_ref < vtype > (this); + } + vtype4_zw_ref < vtype > zw() + { + return vtype4_zw_ref < vtype > (this); + } + vtype4_wx_ref < vtype > wx() + { + return vtype4_wx_ref < vtype > (this); + } + vtype4_wy_ref < vtype > wy() + { + return vtype4_wy_ref < vtype > (this); + } + vtype4_wz_ref < vtype > wz() + { + return vtype4_wz_ref < vtype > (this); + } + vtype4_ww_ref < vtype > ww() + { + return vtype4_ww_ref < vtype > (this); + } + vtype4_xxx_ref < vtype > xxx() + { + return vtype4_xxx_ref < vtype > (this); + } + vtype4_xxy_ref < vtype > xxy() + { + return vtype4_xxy_ref < vtype > (this); + } + vtype4_xxz_ref < vtype > xxz() + { + return vtype4_xxz_ref < vtype > (this); + } + vtype4_xxw_ref < vtype > xxw() + { + return vtype4_xxw_ref < vtype > (this); + } + vtype4_xyx_ref < vtype > xyx() + { + return vtype4_xyx_ref < vtype > (this); + } + vtype4_xyy_ref < vtype > xyy() + { + return vtype4_xyy_ref < vtype > (this); + } + vtype4_xyz_ref < vtype > xyz() + { + return vtype4_xyz_ref < vtype > (this); + } + vtype4_xyw_ref < vtype > xyw() + { + return vtype4_xyw_ref < vtype > (this); + } + vtype4_xzx_ref < vtype > xzx() + { + return vtype4_xzx_ref < vtype > (this); + } + vtype4_xzy_ref < vtype > xzy() + { + return vtype4_xzy_ref < vtype > (this); + } + vtype4_xzz_ref < vtype > xzz() + { + return vtype4_xzz_ref < vtype > (this); + } + vtype4_xzw_ref < vtype > xzw() + { + return vtype4_xzw_ref < vtype > (this); + } + vtype4_xwx_ref < vtype > xwx() + { + return vtype4_xwx_ref < vtype > (this); + } + vtype4_xwy_ref < vtype > xwy() + { + return vtype4_xwy_ref < vtype > (this); + } + vtype4_xwz_ref < vtype > xwz() + { + return vtype4_xwz_ref < vtype > (this); + } + vtype4_xww_ref < vtype > xww() + { + return vtype4_xww_ref < vtype > (this); + } + vtype4_yxx_ref < vtype > yxx() + { + return vtype4_yxx_ref < vtype > (this); + } + vtype4_yxy_ref < vtype > yxy() + { + return vtype4_yxy_ref < vtype > (this); + } + vtype4_yxz_ref < vtype > yxz() + { + return vtype4_yxz_ref < vtype > (this); + } + vtype4_yxw_ref < vtype > yxw() + { + return vtype4_yxw_ref < vtype > (this); + } + vtype4_yyx_ref < vtype > yyx() + { + return vtype4_yyx_ref < vtype > (this); + } + vtype4_yyy_ref < vtype > yyy() + { + return vtype4_yyy_ref < vtype > (this); + } + vtype4_yyz_ref < vtype > yyz() + { + return vtype4_yyz_ref < vtype > (this); + } + vtype4_yyw_ref < vtype > yyw() + { + return vtype4_yyw_ref < vtype > (this); + } + vtype4_yzx_ref < vtype > yzx() + { + return vtype4_yzx_ref < vtype > (this); + } + vtype4_yzy_ref < vtype > yzy() + { + return vtype4_yzy_ref < vtype > (this); + } + vtype4_yzz_ref < vtype > yzz() + { + return vtype4_yzz_ref < vtype > (this); + } + vtype4_yzw_ref < vtype > yzw() + { + return vtype4_yzw_ref < vtype > (this); + } + vtype4_ywx_ref < vtype > ywx() + { + return vtype4_ywx_ref < vtype > (this); + } + vtype4_ywy_ref < vtype > ywy() + { + return vtype4_ywy_ref < vtype > (this); + } + vtype4_ywz_ref < vtype > ywz() + { + return vtype4_ywz_ref < vtype > (this); + } + vtype4_yww_ref < vtype > yww() + { + return vtype4_yww_ref < vtype > (this); + } + vtype4_zxx_ref < vtype > zxx() + { + return vtype4_zxx_ref < vtype > (this); + } + vtype4_zxy_ref < vtype > zxy() + { + return vtype4_zxy_ref < vtype > (this); + } + vtype4_zxz_ref < vtype > zxz() + { + return vtype4_zxz_ref < vtype > (this); + } + vtype4_zxw_ref < vtype > zxw() + { + return vtype4_zxw_ref < vtype > (this); + } + vtype4_zyx_ref < vtype > zyx() + { + return vtype4_zyx_ref < vtype > (this); + } + vtype4_zyy_ref < vtype > zyy() + { + return vtype4_zyy_ref < vtype > (this); + } + vtype4_zyz_ref < vtype > zyz() + { + return vtype4_zyz_ref < vtype > (this); + } + vtype4_zyw_ref < vtype > zyw() + { + return vtype4_zyw_ref < vtype > (this); + } + vtype4_zzx_ref < vtype > zzx() + { + return vtype4_zzx_ref < vtype > (this); + } + vtype4_zzy_ref < vtype > zzy() + { + return vtype4_zzy_ref < vtype > (this); + } + vtype4_zzz_ref < vtype > zzz() + { + return vtype4_zzz_ref < vtype > (this); + } + vtype4_zzw_ref < vtype > zzw() + { + return vtype4_zzw_ref < vtype > (this); + } + vtype4_zwx_ref < vtype > zwx() + { + return vtype4_zwx_ref < vtype > (this); + } + vtype4_zwy_ref < vtype > zwy() + { + return vtype4_zwy_ref < vtype > (this); + } + vtype4_zwz_ref < vtype > zwz() + { + return vtype4_zwz_ref < vtype > (this); + } + vtype4_zww_ref < vtype > zww() + { + return vtype4_zww_ref < vtype > (this); + } + vtype4_wxx_ref < vtype > wxx() + { + return vtype4_wxx_ref < vtype > (this); + } + vtype4_wxy_ref < vtype > wxy() + { + return vtype4_wxy_ref < vtype > (this); + } + vtype4_wxz_ref < vtype > wxz() + { + return vtype4_wxz_ref < vtype > (this); + } + vtype4_wxw_ref < vtype > wxw() + { + return vtype4_wxw_ref < vtype > (this); + } + vtype4_wyx_ref < vtype > wyx() + { + return vtype4_wyx_ref < vtype > (this); + } + vtype4_wyy_ref < vtype > wyy() + { + return vtype4_wyy_ref < vtype > (this); + } + vtype4_wyz_ref < vtype > wyz() + { + return vtype4_wyz_ref < vtype > (this); + } + vtype4_wyw_ref < vtype > wyw() + { + return vtype4_wyw_ref < vtype > (this); + } + vtype4_wzx_ref < vtype > wzx() + { + return vtype4_wzx_ref < vtype > (this); + } + vtype4_wzy_ref < vtype > wzy() + { + return vtype4_wzy_ref < vtype > (this); + } + vtype4_wzz_ref < vtype > wzz() + { + return vtype4_wzz_ref < vtype > (this); + } + vtype4_wzw_ref < vtype > wzw() + { + return vtype4_wzw_ref < vtype > (this); + } + vtype4_wwx_ref < vtype > wwx() + { + return vtype4_wwx_ref < vtype > (this); + } + vtype4_wwy_ref < vtype > wwy() + { + return vtype4_wwy_ref < vtype > (this); + } + vtype4_wwz_ref < vtype > wwz() + { + return vtype4_wwz_ref < vtype > (this); + } + vtype4_www_ref < vtype > www() + { + return vtype4_www_ref < vtype > (this); + } + vtype4_xxxx_ref < vtype > xxxx() + { + return vtype4_xxxx_ref < vtype > (this); + } + vtype4_xxxy_ref < vtype > xxxy() + { + return vtype4_xxxy_ref < vtype > (this); + } + vtype4_xxxz_ref < vtype > xxxz() + { + return vtype4_xxxz_ref < vtype > (this); + } + vtype4_xxxw_ref < vtype > xxxw() + { + return vtype4_xxxw_ref < vtype > (this); + } + vtype4_xxyx_ref < vtype > xxyx() + { + return vtype4_xxyx_ref < vtype > (this); + } + vtype4_xxyy_ref < vtype > xxyy() + { + return vtype4_xxyy_ref < vtype > (this); + } + vtype4_xxyz_ref < vtype > xxyz() + { + return vtype4_xxyz_ref < vtype > (this); + } + vtype4_xxyw_ref < vtype > xxyw() + { + return vtype4_xxyw_ref < vtype > (this); + } + vtype4_xxzx_ref < vtype > xxzx() + { + return vtype4_xxzx_ref < vtype > (this); + } + vtype4_xxzy_ref < vtype > xxzy() + { + return vtype4_xxzy_ref < vtype > (this); + } + vtype4_xxzz_ref < vtype > xxzz() + { + return vtype4_xxzz_ref < vtype > (this); + } + vtype4_xxzw_ref < vtype > xxzw() + { + return vtype4_xxzw_ref < vtype > (this); + } + vtype4_xxwx_ref < vtype > xxwx() + { + return vtype4_xxwx_ref < vtype > (this); + } + vtype4_xxwy_ref < vtype > xxwy() + { + return vtype4_xxwy_ref < vtype > (this); + } + vtype4_xxwz_ref < vtype > xxwz() + { + return vtype4_xxwz_ref < vtype > (this); + } + vtype4_xxww_ref < vtype > xxww() + { + return vtype4_xxww_ref < vtype > (this); + } + vtype4_xyxx_ref < vtype > xyxx() + { + return vtype4_xyxx_ref < vtype > (this); + } + vtype4_xyxy_ref < vtype > xyxy() + { + return vtype4_xyxy_ref < vtype > (this); + } + vtype4_xyxz_ref < vtype > xyxz() + { + return vtype4_xyxz_ref < vtype > (this); + } + vtype4_xyxw_ref < vtype > xyxw() + { + return vtype4_xyxw_ref < vtype > (this); + } + vtype4_xyyx_ref < vtype > xyyx() + { + return vtype4_xyyx_ref < vtype > (this); + } + vtype4_xyyy_ref < vtype > xyyy() + { + return vtype4_xyyy_ref < vtype > (this); + } + vtype4_xyyz_ref < vtype > xyyz() + { + return vtype4_xyyz_ref < vtype > (this); + } + vtype4_xyyw_ref < vtype > xyyw() + { + return vtype4_xyyw_ref < vtype > (this); + } + vtype4_xyzx_ref < vtype > xyzx() + { + return vtype4_xyzx_ref < vtype > (this); + } + vtype4_xyzy_ref < vtype > xyzy() + { + return vtype4_xyzy_ref < vtype > (this); + } + vtype4_xyzz_ref < vtype > xyzz() + { + return vtype4_xyzz_ref < vtype > (this); + } + vtype4_xyzw_ref < vtype > xyzw() + { + return vtype4_xyzw_ref < vtype > (this); + } + vtype4_xywx_ref < vtype > xywx() + { + return vtype4_xywx_ref < vtype > (this); + } + vtype4_xywy_ref < vtype > xywy() + { + return vtype4_xywy_ref < vtype > (this); + } + vtype4_xywz_ref < vtype > xywz() + { + return vtype4_xywz_ref < vtype > (this); + } + vtype4_xyww_ref < vtype > xyww() + { + return vtype4_xyww_ref < vtype > (this); + } + vtype4_xzxx_ref < vtype > xzxx() + { + return vtype4_xzxx_ref < vtype > (this); + } + vtype4_xzxy_ref < vtype > xzxy() + { + return vtype4_xzxy_ref < vtype > (this); + } + vtype4_xzxz_ref < vtype > xzxz() + { + return vtype4_xzxz_ref < vtype > (this); + } + vtype4_xzxw_ref < vtype > xzxw() + { + return vtype4_xzxw_ref < vtype > (this); + } + vtype4_xzyx_ref < vtype > xzyx() + { + return vtype4_xzyx_ref < vtype > (this); + } + vtype4_xzyy_ref < vtype > xzyy() + { + return vtype4_xzyy_ref < vtype > (this); + } + vtype4_xzyz_ref < vtype > xzyz() + { + return vtype4_xzyz_ref < vtype > (this); + } + vtype4_xzyw_ref < vtype > xzyw() + { + return vtype4_xzyw_ref < vtype > (this); + } + vtype4_xzzx_ref < vtype > xzzx() + { + return vtype4_xzzx_ref < vtype > (this); + } + vtype4_xzzy_ref < vtype > xzzy() + { + return vtype4_xzzy_ref < vtype > (this); + } + vtype4_xzzz_ref < vtype > xzzz() + { + return vtype4_xzzz_ref < vtype > (this); + } + vtype4_xzzw_ref < vtype > xzzw() + { + return vtype4_xzzw_ref < vtype > (this); + } + vtype4_xzwx_ref < vtype > xzwx() + { + return vtype4_xzwx_ref < vtype > (this); + } + vtype4_xzwy_ref < vtype > xzwy() + { + return vtype4_xzwy_ref < vtype > (this); + } + vtype4_xzwz_ref < vtype > xzwz() + { + return vtype4_xzwz_ref < vtype > (this); + } + vtype4_xzww_ref < vtype > xzww() + { + return vtype4_xzww_ref < vtype > (this); + } + vtype4_xwxx_ref < vtype > xwxx() + { + return vtype4_xwxx_ref < vtype > (this); + } + vtype4_xwxy_ref < vtype > xwxy() + { + return vtype4_xwxy_ref < vtype > (this); + } + vtype4_xwxz_ref < vtype > xwxz() + { + return vtype4_xwxz_ref < vtype > (this); + } + vtype4_xwxw_ref < vtype > xwxw() + { + return vtype4_xwxw_ref < vtype > (this); + } + vtype4_xwyx_ref < vtype > xwyx() + { + return vtype4_xwyx_ref < vtype > (this); + } + vtype4_xwyy_ref < vtype > xwyy() + { + return vtype4_xwyy_ref < vtype > (this); + } + vtype4_xwyz_ref < vtype > xwyz() + { + return vtype4_xwyz_ref < vtype > (this); + } + vtype4_xwyw_ref < vtype > xwyw() + { + return vtype4_xwyw_ref < vtype > (this); + } + vtype4_xwzx_ref < vtype > xwzx() + { + return vtype4_xwzx_ref < vtype > (this); + } + vtype4_xwzy_ref < vtype > xwzy() + { + return vtype4_xwzy_ref < vtype > (this); + } + vtype4_xwzz_ref < vtype > xwzz() + { + return vtype4_xwzz_ref < vtype > (this); + } + vtype4_xwzw_ref < vtype > xwzw() + { + return vtype4_xwzw_ref < vtype > (this); + } + vtype4_xwwx_ref < vtype > xwwx() + { + return vtype4_xwwx_ref < vtype > (this); + } + vtype4_xwwy_ref < vtype > xwwy() + { + return vtype4_xwwy_ref < vtype > (this); + } + vtype4_xwwz_ref < vtype > xwwz() + { + return vtype4_xwwz_ref < vtype > (this); + } + vtype4_xwww_ref < vtype > xwww() + { + return vtype4_xwww_ref < vtype > (this); + } + vtype4_yxxx_ref < vtype > yxxx() + { + return vtype4_yxxx_ref < vtype > (this); + } + vtype4_yxxy_ref < vtype > yxxy() + { + return vtype4_yxxy_ref < vtype > (this); + } + vtype4_yxxz_ref < vtype > yxxz() + { + return vtype4_yxxz_ref < vtype > (this); + } + vtype4_yxxw_ref < vtype > yxxw() + { + return vtype4_yxxw_ref < vtype > (this); + } + vtype4_yxyx_ref < vtype > yxyx() + { + return vtype4_yxyx_ref < vtype > (this); + } + vtype4_yxyy_ref < vtype > yxyy() + { + return vtype4_yxyy_ref < vtype > (this); + } + vtype4_yxyz_ref < vtype > yxyz() + { + return vtype4_yxyz_ref < vtype > (this); + } + vtype4_yxyw_ref < vtype > yxyw() + { + return vtype4_yxyw_ref < vtype > (this); + } + vtype4_yxzx_ref < vtype > yxzx() + { + return vtype4_yxzx_ref < vtype > (this); + } + vtype4_yxzy_ref < vtype > yxzy() + { + return vtype4_yxzy_ref < vtype > (this); + } + vtype4_yxzz_ref < vtype > yxzz() + { + return vtype4_yxzz_ref < vtype > (this); + } + vtype4_yxzw_ref < vtype > yxzw() + { + return vtype4_yxzw_ref < vtype > (this); + } + vtype4_yxwx_ref < vtype > yxwx() + { + return vtype4_yxwx_ref < vtype > (this); + } + vtype4_yxwy_ref < vtype > yxwy() + { + return vtype4_yxwy_ref < vtype > (this); + } + vtype4_yxwz_ref < vtype > yxwz() + { + return vtype4_yxwz_ref < vtype > (this); + } + vtype4_yxww_ref < vtype > yxww() + { + return vtype4_yxww_ref < vtype > (this); + } + vtype4_yyxx_ref < vtype > yyxx() + { + return vtype4_yyxx_ref < vtype > (this); + } + vtype4_yyxy_ref < vtype > yyxy() + { + return vtype4_yyxy_ref < vtype > (this); + } + vtype4_yyxz_ref < vtype > yyxz() + { + return vtype4_yyxz_ref < vtype > (this); + } + vtype4_yyxw_ref < vtype > yyxw() + { + return vtype4_yyxw_ref < vtype > (this); + } + vtype4_yyyx_ref < vtype > yyyx() + { + return vtype4_yyyx_ref < vtype > (this); + } + vtype4_yyyy_ref < vtype > yyyy() + { + return vtype4_yyyy_ref < vtype > (this); + } + vtype4_yyyz_ref < vtype > yyyz() + { + return vtype4_yyyz_ref < vtype > (this); + } + vtype4_yyyw_ref < vtype > yyyw() + { + return vtype4_yyyw_ref < vtype > (this); + } + vtype4_yyzx_ref < vtype > yyzx() + { + return vtype4_yyzx_ref < vtype > (this); + } + vtype4_yyzy_ref < vtype > yyzy() + { + return vtype4_yyzy_ref < vtype > (this); + } + vtype4_yyzz_ref < vtype > yyzz() + { + return vtype4_yyzz_ref < vtype > (this); + } + vtype4_yyzw_ref < vtype > yyzw() + { + return vtype4_yyzw_ref < vtype > (this); + } + vtype4_yywx_ref < vtype > yywx() + { + return vtype4_yywx_ref < vtype > (this); + } + vtype4_yywy_ref < vtype > yywy() + { + return vtype4_yywy_ref < vtype > (this); + } + vtype4_yywz_ref < vtype > yywz() + { + return vtype4_yywz_ref < vtype > (this); + } + vtype4_yyww_ref < vtype > yyww() + { + return vtype4_yyww_ref < vtype > (this); + } + vtype4_yzxx_ref < vtype > yzxx() + { + return vtype4_yzxx_ref < vtype > (this); + } + vtype4_yzxy_ref < vtype > yzxy() + { + return vtype4_yzxy_ref < vtype > (this); + } + vtype4_yzxz_ref < vtype > yzxz() + { + return vtype4_yzxz_ref < vtype > (this); + } + vtype4_yzxw_ref < vtype > yzxw() + { + return vtype4_yzxw_ref < vtype > (this); + } + vtype4_yzyx_ref < vtype > yzyx() + { + return vtype4_yzyx_ref < vtype > (this); + } + vtype4_yzyy_ref < vtype > yzyy() + { + return vtype4_yzyy_ref < vtype > (this); + } + vtype4_yzyz_ref < vtype > yzyz() + { + return vtype4_yzyz_ref < vtype > (this); + } + vtype4_yzyw_ref < vtype > yzyw() + { + return vtype4_yzyw_ref < vtype > (this); + } + vtype4_yzzx_ref < vtype > yzzx() + { + return vtype4_yzzx_ref < vtype > (this); + } + vtype4_yzzy_ref < vtype > yzzy() + { + return vtype4_yzzy_ref < vtype > (this); + } + vtype4_yzzz_ref < vtype > yzzz() + { + return vtype4_yzzz_ref < vtype > (this); + } + vtype4_yzzw_ref < vtype > yzzw() + { + return vtype4_yzzw_ref < vtype > (this); + } + vtype4_yzwx_ref < vtype > yzwx() + { + return vtype4_yzwx_ref < vtype > (this); + } + vtype4_yzwy_ref < vtype > yzwy() + { + return vtype4_yzwy_ref < vtype > (this); + } + vtype4_yzwz_ref < vtype > yzwz() + { + return vtype4_yzwz_ref < vtype > (this); + } + vtype4_yzww_ref < vtype > yzww() + { + return vtype4_yzww_ref < vtype > (this); + } + vtype4_ywxx_ref < vtype > ywxx() + { + return vtype4_ywxx_ref < vtype > (this); + } + vtype4_ywxy_ref < vtype > ywxy() + { + return vtype4_ywxy_ref < vtype > (this); + } + vtype4_ywxz_ref < vtype > ywxz() + { + return vtype4_ywxz_ref < vtype > (this); + } + vtype4_ywxw_ref < vtype > ywxw() + { + return vtype4_ywxw_ref < vtype > (this); + } + vtype4_ywyx_ref < vtype > ywyx() + { + return vtype4_ywyx_ref < vtype > (this); + } + vtype4_ywyy_ref < vtype > ywyy() + { + return vtype4_ywyy_ref < vtype > (this); + } + vtype4_ywyz_ref < vtype > ywyz() + { + return vtype4_ywyz_ref < vtype > (this); + } + vtype4_ywyw_ref < vtype > ywyw() + { + return vtype4_ywyw_ref < vtype > (this); + } + vtype4_ywzx_ref < vtype > ywzx() + { + return vtype4_ywzx_ref < vtype > (this); + } + vtype4_ywzy_ref < vtype > ywzy() + { + return vtype4_ywzy_ref < vtype > (this); + } + vtype4_ywzz_ref < vtype > ywzz() + { + return vtype4_ywzz_ref < vtype > (this); + } + vtype4_ywzw_ref < vtype > ywzw() + { + return vtype4_ywzw_ref < vtype > (this); + } + vtype4_ywwx_ref < vtype > ywwx() + { + return vtype4_ywwx_ref < vtype > (this); + } + vtype4_ywwy_ref < vtype > ywwy() + { + return vtype4_ywwy_ref < vtype > (this); + } + vtype4_ywwz_ref < vtype > ywwz() + { + return vtype4_ywwz_ref < vtype > (this); + } + vtype4_ywww_ref < vtype > ywww() + { + return vtype4_ywww_ref < vtype > (this); + } + vtype4_zxxx_ref < vtype > zxxx() + { + return vtype4_zxxx_ref < vtype > (this); + } + vtype4_zxxy_ref < vtype > zxxy() + { + return vtype4_zxxy_ref < vtype > (this); + } + vtype4_zxxz_ref < vtype > zxxz() + { + return vtype4_zxxz_ref < vtype > (this); + } + vtype4_zxxw_ref < vtype > zxxw() + { + return vtype4_zxxw_ref < vtype > (this); + } + vtype4_zxyx_ref < vtype > zxyx() + { + return vtype4_zxyx_ref < vtype > (this); + } + vtype4_zxyy_ref < vtype > zxyy() + { + return vtype4_zxyy_ref < vtype > (this); + } + vtype4_zxyz_ref < vtype > zxyz() + { + return vtype4_zxyz_ref < vtype > (this); + } + vtype4_zxyw_ref < vtype > zxyw() + { + return vtype4_zxyw_ref < vtype > (this); + } + vtype4_zxzx_ref < vtype > zxzx() + { + return vtype4_zxzx_ref < vtype > (this); + } + vtype4_zxzy_ref < vtype > zxzy() + { + return vtype4_zxzy_ref < vtype > (this); + } + vtype4_zxzz_ref < vtype > zxzz() + { + return vtype4_zxzz_ref < vtype > (this); + } + vtype4_zxzw_ref < vtype > zxzw() + { + return vtype4_zxzw_ref < vtype > (this); + } + vtype4_zxwx_ref < vtype > zxwx() + { + return vtype4_zxwx_ref < vtype > (this); + } + vtype4_zxwy_ref < vtype > zxwy() + { + return vtype4_zxwy_ref < vtype > (this); + } + vtype4_zxwz_ref < vtype > zxwz() + { + return vtype4_zxwz_ref < vtype > (this); + } + vtype4_zxww_ref < vtype > zxww() + { + return vtype4_zxww_ref < vtype > (this); + } + vtype4_zyxx_ref < vtype > zyxx() + { + return vtype4_zyxx_ref < vtype > (this); + } + vtype4_zyxy_ref < vtype > zyxy() + { + return vtype4_zyxy_ref < vtype > (this); + } + vtype4_zyxz_ref < vtype > zyxz() + { + return vtype4_zyxz_ref < vtype > (this); + } + vtype4_zyxw_ref < vtype > zyxw() + { + return vtype4_zyxw_ref < vtype > (this); + } + vtype4_zyyx_ref < vtype > zyyx() + { + return vtype4_zyyx_ref < vtype > (this); + } + vtype4_zyyy_ref < vtype > zyyy() + { + return vtype4_zyyy_ref < vtype > (this); + } + vtype4_zyyz_ref < vtype > zyyz() + { + return vtype4_zyyz_ref < vtype > (this); + } + vtype4_zyyw_ref < vtype > zyyw() + { + return vtype4_zyyw_ref < vtype > (this); + } + vtype4_zyzx_ref < vtype > zyzx() + { + return vtype4_zyzx_ref < vtype > (this); + } + vtype4_zyzy_ref < vtype > zyzy() + { + return vtype4_zyzy_ref < vtype > (this); + } + vtype4_zyzz_ref < vtype > zyzz() + { + return vtype4_zyzz_ref < vtype > (this); + } + vtype4_zyzw_ref < vtype > zyzw() + { + return vtype4_zyzw_ref < vtype > (this); + } + vtype4_zywx_ref < vtype > zywx() + { + return vtype4_zywx_ref < vtype > (this); + } + vtype4_zywy_ref < vtype > zywy() + { + return vtype4_zywy_ref < vtype > (this); + } + vtype4_zywz_ref < vtype > zywz() + { + return vtype4_zywz_ref < vtype > (this); + } + vtype4_zyww_ref < vtype > zyww() + { + return vtype4_zyww_ref < vtype > (this); + } + vtype4_zzxx_ref < vtype > zzxx() + { + return vtype4_zzxx_ref < vtype > (this); + } + vtype4_zzxy_ref < vtype > zzxy() + { + return vtype4_zzxy_ref < vtype > (this); + } + vtype4_zzxz_ref < vtype > zzxz() + { + return vtype4_zzxz_ref < vtype > (this); + } + vtype4_zzxw_ref < vtype > zzxw() + { + return vtype4_zzxw_ref < vtype > (this); + } + vtype4_zzyx_ref < vtype > zzyx() + { + return vtype4_zzyx_ref < vtype > (this); + } + vtype4_zzyy_ref < vtype > zzyy() + { + return vtype4_zzyy_ref < vtype > (this); + } + vtype4_zzyz_ref < vtype > zzyz() + { + return vtype4_zzyz_ref < vtype > (this); + } + vtype4_zzyw_ref < vtype > zzyw() + { + return vtype4_zzyw_ref < vtype > (this); + } + vtype4_zzzx_ref < vtype > zzzx() + { + return vtype4_zzzx_ref < vtype > (this); + } + vtype4_zzzy_ref < vtype > zzzy() + { + return vtype4_zzzy_ref < vtype > (this); + } + vtype4_zzzz_ref < vtype > zzzz() + { + return vtype4_zzzz_ref < vtype > (this); + } + vtype4_zzzw_ref < vtype > zzzw() + { + return vtype4_zzzw_ref < vtype > (this); + } + vtype4_zzwx_ref < vtype > zzwx() + { + return vtype4_zzwx_ref < vtype > (this); + } + vtype4_zzwy_ref < vtype > zzwy() + { + return vtype4_zzwy_ref < vtype > (this); + } + vtype4_zzwz_ref < vtype > zzwz() + { + return vtype4_zzwz_ref < vtype > (this); + } + vtype4_zzww_ref < vtype > zzww() + { + return vtype4_zzww_ref < vtype > (this); + } + vtype4_zwxx_ref < vtype > zwxx() + { + return vtype4_zwxx_ref < vtype > (this); + } + vtype4_zwxy_ref < vtype > zwxy() + { + return vtype4_zwxy_ref < vtype > (this); + } + vtype4_zwxz_ref < vtype > zwxz() + { + return vtype4_zwxz_ref < vtype > (this); + } + vtype4_zwxw_ref < vtype > zwxw() + { + return vtype4_zwxw_ref < vtype > (this); + } + vtype4_zwyx_ref < vtype > zwyx() + { + return vtype4_zwyx_ref < vtype > (this); + } + vtype4_zwyy_ref < vtype > zwyy() + { + return vtype4_zwyy_ref < vtype > (this); + } + vtype4_zwyz_ref < vtype > zwyz() + { + return vtype4_zwyz_ref < vtype > (this); + } + vtype4_zwyw_ref < vtype > zwyw() + { + return vtype4_zwyw_ref < vtype > (this); + } + vtype4_zwzx_ref < vtype > zwzx() + { + return vtype4_zwzx_ref < vtype > (this); + } + vtype4_zwzy_ref < vtype > zwzy() + { + return vtype4_zwzy_ref < vtype > (this); + } + vtype4_zwzz_ref < vtype > zwzz() + { + return vtype4_zwzz_ref < vtype > (this); + } + vtype4_zwzw_ref < vtype > zwzw() + { + return vtype4_zwzw_ref < vtype > (this); + } + vtype4_zwwx_ref < vtype > zwwx() + { + return vtype4_zwwx_ref < vtype > (this); + } + vtype4_zwwy_ref < vtype > zwwy() + { + return vtype4_zwwy_ref < vtype > (this); + } + vtype4_zwwz_ref < vtype > zwwz() + { + return vtype4_zwwz_ref < vtype > (this); + } + vtype4_zwww_ref < vtype > zwww() + { + return vtype4_zwww_ref < vtype > (this); + } + vtype4_wxxx_ref < vtype > wxxx() + { + return vtype4_wxxx_ref < vtype > (this); + } + vtype4_wxxy_ref < vtype > wxxy() + { + return vtype4_wxxy_ref < vtype > (this); + } + vtype4_wxxz_ref < vtype > wxxz() + { + return vtype4_wxxz_ref < vtype > (this); + } + vtype4_wxxw_ref < vtype > wxxw() + { + return vtype4_wxxw_ref < vtype > (this); + } + vtype4_wxyx_ref < vtype > wxyx() + { + return vtype4_wxyx_ref < vtype > (this); + } + vtype4_wxyy_ref < vtype > wxyy() + { + return vtype4_wxyy_ref < vtype > (this); + } + vtype4_wxyz_ref < vtype > wxyz() + { + return vtype4_wxyz_ref < vtype > (this); + } + vtype4_wxyw_ref < vtype > wxyw() + { + return vtype4_wxyw_ref < vtype > (this); + } + vtype4_wxzx_ref < vtype > wxzx() + { + return vtype4_wxzx_ref < vtype > (this); + } + vtype4_wxzy_ref < vtype > wxzy() + { + return vtype4_wxzy_ref < vtype > (this); + } + vtype4_wxzz_ref < vtype > wxzz() + { + return vtype4_wxzz_ref < vtype > (this); + } + vtype4_wxzw_ref < vtype > wxzw() + { + return vtype4_wxzw_ref < vtype > (this); + } + vtype4_wxwx_ref < vtype > wxwx() + { + return vtype4_wxwx_ref < vtype > (this); + } + vtype4_wxwy_ref < vtype > wxwy() + { + return vtype4_wxwy_ref < vtype > (this); + } + vtype4_wxwz_ref < vtype > wxwz() + { + return vtype4_wxwz_ref < vtype > (this); + } + vtype4_wxww_ref < vtype > wxww() + { + return vtype4_wxww_ref < vtype > (this); + } + vtype4_wyxx_ref < vtype > wyxx() + { + return vtype4_wyxx_ref < vtype > (this); + } + vtype4_wyxy_ref < vtype > wyxy() + { + return vtype4_wyxy_ref < vtype > (this); + } + vtype4_wyxz_ref < vtype > wyxz() + { + return vtype4_wyxz_ref < vtype > (this); + } + vtype4_wyxw_ref < vtype > wyxw() + { + return vtype4_wyxw_ref < vtype > (this); + } + vtype4_wyyx_ref < vtype > wyyx() + { + return vtype4_wyyx_ref < vtype > (this); + } + vtype4_wyyy_ref < vtype > wyyy() + { + return vtype4_wyyy_ref < vtype > (this); + } + vtype4_wyyz_ref < vtype > wyyz() + { + return vtype4_wyyz_ref < vtype > (this); + } + vtype4_wyyw_ref < vtype > wyyw() + { + return vtype4_wyyw_ref < vtype > (this); + } + vtype4_wyzx_ref < vtype > wyzx() + { + return vtype4_wyzx_ref < vtype > (this); + } + vtype4_wyzy_ref < vtype > wyzy() + { + return vtype4_wyzy_ref < vtype > (this); + } + vtype4_wyzz_ref < vtype > wyzz() + { + return vtype4_wyzz_ref < vtype > (this); + } + vtype4_wyzw_ref < vtype > wyzw() + { + return vtype4_wyzw_ref < vtype > (this); + } + vtype4_wywx_ref < vtype > wywx() + { + return vtype4_wywx_ref < vtype > (this); + } + vtype4_wywy_ref < vtype > wywy() + { + return vtype4_wywy_ref < vtype > (this); + } + vtype4_wywz_ref < vtype > wywz() + { + return vtype4_wywz_ref < vtype > (this); + } + vtype4_wyww_ref < vtype > wyww() + { + return vtype4_wyww_ref < vtype > (this); + } + vtype4_wzxx_ref < vtype > wzxx() + { + return vtype4_wzxx_ref < vtype > (this); + } + vtype4_wzxy_ref < vtype > wzxy() + { + return vtype4_wzxy_ref < vtype > (this); + } + vtype4_wzxz_ref < vtype > wzxz() + { + return vtype4_wzxz_ref < vtype > (this); + } + vtype4_wzxw_ref < vtype > wzxw() + { + return vtype4_wzxw_ref < vtype > (this); + } + vtype4_wzyx_ref < vtype > wzyx() + { + return vtype4_wzyx_ref < vtype > (this); + } + vtype4_wzyy_ref < vtype > wzyy() + { + return vtype4_wzyy_ref < vtype > (this); + } + vtype4_wzyz_ref < vtype > wzyz() + { + return vtype4_wzyz_ref < vtype > (this); + } + vtype4_wzyw_ref < vtype > wzyw() + { + return vtype4_wzyw_ref < vtype > (this); + } + vtype4_wzzx_ref < vtype > wzzx() + { + return vtype4_wzzx_ref < vtype > (this); + } + vtype4_wzzy_ref < vtype > wzzy() + { + return vtype4_wzzy_ref < vtype > (this); + } + vtype4_wzzz_ref < vtype > wzzz() + { + return vtype4_wzzz_ref < vtype > (this); + } + vtype4_wzzw_ref < vtype > wzzw() + { + return vtype4_wzzw_ref < vtype > (this); + } + vtype4_wzwx_ref < vtype > wzwx() + { + return vtype4_wzwx_ref < vtype > (this); + } + vtype4_wzwy_ref < vtype > wzwy() + { + return vtype4_wzwy_ref < vtype > (this); + } + vtype4_wzwz_ref < vtype > wzwz() + { + return vtype4_wzwz_ref < vtype > (this); + } + vtype4_wzww_ref < vtype > wzww() + { + return vtype4_wzww_ref < vtype > (this); + } + vtype4_wwxx_ref < vtype > wwxx() + { + return vtype4_wwxx_ref < vtype > (this); + } + vtype4_wwxy_ref < vtype > wwxy() + { + return vtype4_wwxy_ref < vtype > (this); + } + vtype4_wwxz_ref < vtype > wwxz() + { + return vtype4_wwxz_ref < vtype > (this); + } + vtype4_wwxw_ref < vtype > wwxw() + { + return vtype4_wwxw_ref < vtype > (this); + } + vtype4_wwyx_ref < vtype > wwyx() + { + return vtype4_wwyx_ref < vtype > (this); + } + vtype4_wwyy_ref < vtype > wwyy() + { + return vtype4_wwyy_ref < vtype > (this); + } + vtype4_wwyz_ref < vtype > wwyz() + { + return vtype4_wwyz_ref < vtype > (this); + } + vtype4_wwyw_ref < vtype > wwyw() + { + return vtype4_wwyw_ref < vtype > (this); + } + vtype4_wwzx_ref < vtype > wwzx() + { + return vtype4_wwzx_ref < vtype > (this); + } + vtype4_wwzy_ref < vtype > wwzy() + { + return vtype4_wwzy_ref < vtype > (this); + } + vtype4_wwzz_ref < vtype > wwzz() + { + return vtype4_wwzz_ref < vtype > (this); + } + vtype4_wwzw_ref < vtype > wwzw() + { + return vtype4_wwzw_ref < vtype > (this); + } + vtype4_wwwx_ref < vtype > wwwx() + { + return vtype4_wwwx_ref < vtype > (this); + } + vtype4_wwwy_ref < vtype > wwwy() + { + return vtype4_wwwy_ref < vtype > (this); + } + vtype4_wwwz_ref < vtype > wwwz() + { + return vtype4_wwwz_ref < vtype > (this); + } + vtype4_wwww_ref < vtype > wwww() + { + return vtype4_wwww_ref < vtype > (this); + } +}; + +template < typename vtype > vtype2_xy_ref < vtype > &vtype2_xy_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + return *this; +} + +template < typename vtype > vtype2_yx_ref < vtype > &vtype2_yx_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + return *this; +} + +template < typename vtype > vtype3_xy_ref < vtype > &vtype3_xy_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + return *this; +} + +template < typename vtype > vtype3_xz_ref < vtype > &vtype3_xz_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + return *this; +} + +template < typename vtype > vtype3_yx_ref < vtype > &vtype3_yx_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + return *this; +} + +template < typename vtype > vtype3_yz_ref < vtype > &vtype3_yz_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + return *this; +} + +template < typename vtype > vtype3_zx_ref < vtype > &vtype3_zx_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + return *this; +} + +template < typename vtype > vtype3_zy_ref < vtype > &vtype3_zy_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + return *this; +} + +template < typename vtype > vtype3_xyz_ref < vtype > &vtype3_xyz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype3_xzy_ref < vtype > &vtype3_xzy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype3_yxz_ref < vtype > &vtype3_yxz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype3_yzx_ref < vtype > &vtype3_yzx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype3_zxy_ref < vtype > &vtype3_zxy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype3_zyx_ref < vtype > &vtype3_zyx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_xy_ref < vtype > &vtype4_xy_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + return *this; +} + +template < typename vtype > vtype4_xz_ref < vtype > &vtype4_xz_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + return *this; +} + +template < typename vtype > vtype4_xw_ref < vtype > &vtype4_xw_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->x = other.x; + v->w = other.y; + return *this; +} + +template < typename vtype > vtype4_yx_ref < vtype > &vtype4_yx_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + return *this; +} + +template < typename vtype > vtype4_yz_ref < vtype > &vtype4_yz_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + return *this; +} + +template < typename vtype > vtype4_yw_ref < vtype > &vtype4_yw_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->y = other.x; + v->w = other.y; + return *this; +} + +template < typename vtype > vtype4_zx_ref < vtype > &vtype4_zx_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + return *this; +} + +template < typename vtype > vtype4_zy_ref < vtype > &vtype4_zy_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + return *this; +} + +template < typename vtype > vtype4_zw_ref < vtype > &vtype4_zw_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->z = other.x; + v->w = other.y; + return *this; +} + +template < typename vtype > vtype4_wx_ref < vtype > &vtype4_wx_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->w = other.x; + v->x = other.y; + return *this; +} + +template < typename vtype > vtype4_wy_ref < vtype > &vtype4_wy_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->w = other.x; + v->y = other.y; + return *this; +} + +template < typename vtype > vtype4_wz_ref < vtype > &vtype4_wz_ref < vtype >::operator=(const vtype2 < vtype > &other) +{ + v->w = other.x; + v->z = other.y; + return *this; +} + +template < typename vtype > vtype4_xyz_ref < vtype > &vtype4_xyz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype4_xyw_ref < vtype > &vtype4_xyw_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + v->w = other.z; + return *this; +} + +template < typename vtype > vtype4_xzy_ref < vtype > &vtype4_xzy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype4_xzw_ref < vtype > &vtype4_xzw_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + v->w = other.z; + return *this; +} + +template < typename vtype > vtype4_xwy_ref < vtype > &vtype4_xwy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->w = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype4_xwz_ref < vtype > &vtype4_xwz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->x = other.x; + v->w = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype4_yxz_ref < vtype > &vtype4_yxz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype4_yxw_ref < vtype > &vtype4_yxw_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + v->w = other.z; + return *this; +} + +template < typename vtype > vtype4_yzx_ref < vtype > &vtype4_yzx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_yzw_ref < vtype > &vtype4_yzw_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + v->w = other.z; + return *this; +} + +template < typename vtype > vtype4_ywx_ref < vtype > &vtype4_ywx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->w = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_ywz_ref < vtype > &vtype4_ywz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->y = other.x; + v->w = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype4_zxy_ref < vtype > &vtype4_zxy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype4_zxw_ref < vtype > &vtype4_zxw_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + v->w = other.z; + return *this; +} + +template < typename vtype > vtype4_zyx_ref < vtype > &vtype4_zyx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_zyw_ref < vtype > &vtype4_zyw_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + v->w = other.z; + return *this; +} + +template < typename vtype > vtype4_zwx_ref < vtype > &vtype4_zwx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->w = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_zwy_ref < vtype > &vtype4_zwy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->z = other.x; + v->w = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype4_wxy_ref < vtype > &vtype4_wxy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->w = other.x; + v->x = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype4_wxz_ref < vtype > &vtype4_wxz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->w = other.x; + v->x = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype4_wyx_ref < vtype > &vtype4_wyx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->w = other.x; + v->y = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_wyz_ref < vtype > &vtype4_wyz_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->w = other.x; + v->y = other.y; + v->z = other.z; + return *this; +} + +template < typename vtype > vtype4_wzx_ref < vtype > &vtype4_wzx_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->w = other.x; + v->z = other.y; + v->x = other.z; + return *this; +} + +template < typename vtype > vtype4_wzy_ref < vtype > &vtype4_wzy_ref < vtype >::operator=(const vtype3 < vtype > &other) +{ + v->w = other.x; + v->z = other.y; + v->y = other.z; + return *this; +} + +template < typename vtype > vtype4_xyzw_ref < vtype > &vtype4_xyzw_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + v->z = other.z; + v->w = other.w; + return *this; +} + +template < typename vtype > vtype4_xywz_ref < vtype > &vtype4_xywz_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->x = other.x; + v->y = other.y; + v->w = other.z; + v->z = other.w; + return *this; +} + +template < typename vtype > vtype4_xzyw_ref < vtype > &vtype4_xzyw_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + v->y = other.z; + v->w = other.w; + return *this; +} + +template < typename vtype > vtype4_xzwy_ref < vtype > &vtype4_xzwy_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->x = other.x; + v->z = other.y; + v->w = other.z; + v->y = other.w; + return *this; +} + +template < typename vtype > vtype4_xwyz_ref < vtype > &vtype4_xwyz_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->x = other.x; + v->w = other.y; + v->y = other.z; + v->z = other.w; + return *this; +} + +template < typename vtype > vtype4_xwzy_ref < vtype > &vtype4_xwzy_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->x = other.x; + v->w = other.y; + v->z = other.z; + v->y = other.w; + return *this; +} + +template < typename vtype > vtype4_yxzw_ref < vtype > &vtype4_yxzw_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + v->z = other.z; + v->w = other.w; + return *this; +} + +template < typename vtype > vtype4_yxwz_ref < vtype > &vtype4_yxwz_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->y = other.x; + v->x = other.y; + v->w = other.z; + v->z = other.w; + return *this; +} + +template < typename vtype > vtype4_yzxw_ref < vtype > &vtype4_yzxw_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + v->x = other.z; + v->w = other.w; + return *this; +} + +template < typename vtype > vtype4_yzwx_ref < vtype > &vtype4_yzwx_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->y = other.x; + v->z = other.y; + v->w = other.z; + v->x = other.w; + return *this; +} + +template < typename vtype > vtype4_ywxz_ref < vtype > &vtype4_ywxz_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->y = other.x; + v->w = other.y; + v->x = other.z; + v->z = other.w; + return *this; +} + +template < typename vtype > vtype4_ywzx_ref < vtype > &vtype4_ywzx_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->y = other.x; + v->w = other.y; + v->z = other.z; + v->x = other.w; + return *this; +} + +template < typename vtype > vtype4_zxyw_ref < vtype > &vtype4_zxyw_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + v->y = other.z; + v->w = other.w; + return *this; +} + +template < typename vtype > vtype4_zxwy_ref < vtype > &vtype4_zxwy_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->z = other.x; + v->x = other.y; + v->w = other.z; + v->y = other.w; + return *this; +} + +template < typename vtype > vtype4_zyxw_ref < vtype > &vtype4_zyxw_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + v->x = other.z; + v->w = other.w; + return *this; +} + +template < typename vtype > vtype4_zywx_ref < vtype > &vtype4_zywx_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->z = other.x; + v->y = other.y; + v->w = other.z; + v->x = other.w; + return *this; +} + +template < typename vtype > vtype4_zwxy_ref < vtype > &vtype4_zwxy_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->z = other.x; + v->w = other.y; + v->x = other.z; + v->y = other.w; + return *this; +} + +template < typename vtype > vtype4_zwyx_ref < vtype > &vtype4_zwyx_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->z = other.x; + v->w = other.y; + v->y = other.z; + v->x = other.w; + return *this; +} + +template < typename vtype > vtype4_wxyz_ref < vtype > &vtype4_wxyz_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->w = other.x; + v->x = other.y; + v->y = other.z; + v->z = other.w; + return *this; +} + +template < typename vtype > vtype4_wxzy_ref < vtype > &vtype4_wxzy_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->w = other.x; + v->x = other.y; + v->z = other.z; + v->y = other.w; + return *this; +} + +template < typename vtype > vtype4_wyxz_ref < vtype > &vtype4_wyxz_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->w = other.x; + v->y = other.y; + v->x = other.z; + v->z = other.w; + return *this; +} + +template < typename vtype > vtype4_wyzx_ref < vtype > &vtype4_wyzx_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->w = other.x; + v->y = other.y; + v->z = other.z; + v->x = other.w; + return *this; +} + +template < typename vtype > vtype4_wzxy_ref < vtype > &vtype4_wzxy_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->w = other.x; + v->z = other.y; + v->x = other.z; + v->y = other.w; + return *this; +} + +template < typename vtype > vtype4_wzyx_ref < vtype > &vtype4_wzyx_ref < vtype >::operator=(const vtype4 < vtype > &other) +{ + v->w = other.x; + v->z = other.y; + v->y = other.z; + v->x = other.w; + return *this; +} + +template < typename vtype > vtype2 < vtype >::vtype2(const vtype2_xx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype2_xy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype2_yx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype2_yy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_xx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_xy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_xz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_yx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_yy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_yz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_zx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_zy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype3_zz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_xx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_xy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_xz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_xw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_yx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_yy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_yz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_yw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_zx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_zy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_zz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_zw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_wx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_wy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_wz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; +} +template < typename vtype > vtype2 < vtype >::vtype2(const vtype4_ww_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_xxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_xxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_xyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_xyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_yxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_yxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_yyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype2_yyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_xzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_yzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype3_zzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xxw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xyw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xzw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xwx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xwy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xwz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_xww_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yxw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yyw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yzw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_ywx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_ywy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_ywz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_yww_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zxw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zyw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zzw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zwx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zwy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zwz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_zww_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wxx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wxy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wxz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wxw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wyx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wyy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wyz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wyw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wzx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wzy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wzz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wzw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->w; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wwx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->x; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wwy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->y; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_wwz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->z; +} +template < typename vtype > vtype3 < vtype >::vtype3(const vtype4_www_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xxxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xxxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xxyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xxyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xyxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xyxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xyyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_xyyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yxxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yxxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yxyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yxyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yyxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yyxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yyyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype2_yyyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xxzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xyzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_xzzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yxzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yyzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_yzzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zxzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zyzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype3_zzzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxxw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxyw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxzw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxwx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxwy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxwz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xxww_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->x; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyxw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyyw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyzw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xywx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xywy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xywz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xyww_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->y; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzxw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzyw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzzw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzwx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzwy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzwz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xzww_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->z; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwxx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwxy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwxz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwxw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwyx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwyy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwyz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwyw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwzx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwzy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwzz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwzw_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwwx_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwwy_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwwz_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_xwww_ref < vtype > &v) +{ + x = v.v->x; + y = v.v->w; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxxw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxyw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxzw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxwx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxwy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxwz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yxww_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->x; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyxw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyyw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyzw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yywx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yywy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yywz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yyww_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->y; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzxw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzyw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzzw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzwx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzwy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzwz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_yzww_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->z; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywxx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywxy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywxz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywxw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywyx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywyy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywyz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywyw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywzx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywzy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywzz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywzw_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywwx_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywwy_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywwz_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_ywww_ref < vtype > &v) +{ + x = v.v->y; + y = v.v->w; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxxw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxyw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxzw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxwx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxwy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxwz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zxww_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->x; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyxw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyyw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyzw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zywx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zywy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zywz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zyww_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->y; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzxw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzyw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzzw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzwx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzwy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzwz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zzww_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->z; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwxx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwxy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwxz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwxw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwyx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwyy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwyz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwyw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwzx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwzy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwzz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwzw_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwwx_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwwy_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwwz_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_zwww_ref < vtype > &v) +{ + x = v.v->z; + y = v.v->w; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxxx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxxy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxxz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxxw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxyx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxyy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxyz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxyw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxzx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxzy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxzz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxzw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxwx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxwy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxwz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wxww_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->x; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyxx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyxy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyxz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyxw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyyx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyyy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyyz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyyw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyzx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyzy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyzz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyzw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wywx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wywy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wywz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wyww_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->y; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzxx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzxy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzxz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzxw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzyx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzyy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzyz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzyw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzzx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzzy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzzz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzzw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzwx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzwy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzwz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wzww_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->z; + z = v.v->w; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwxx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->x; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwxy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->x; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwxz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->x; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwxw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->x; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwyx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->y; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwyy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->y; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwyz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->y; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwyw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->y; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwzx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->z; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwzy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->z; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwzz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->z; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwzw_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->z; + w = v.v->w; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwwx_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->w; + w = v.v->x; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwwy_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->w; + w = v.v->y; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwwz_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->w; + w = v.v->z; +} +template < typename vtype > vtype4 < vtype >::vtype4(const vtype4_wwww_ref < vtype > &v) +{ + x = v.v->w; + y = v.v->w; + z = v.v->w; + w = v.v->w; +} +typedef vtype2 < float >float2; +typedef vtype3 < float >float3; +typedef vtype4 < float >float4; +typedef vtype2 < double >double2; +typedef vtype3 < double >double3; +typedef vtype4 < double >double4; +typedef vtype2 < int >int2; +typedef vtype3 < int >int3; +typedef vtype4 < int >int4; +typedef vtype2 < uint > uint2; +typedef vtype3 < uint > uint3; +typedef vtype4 < uint > uint4; +typedef vtype2 < short >short2; +typedef vtype3 < short >short3; +typedef vtype4 < short >short4; +typedef vtype2 < ushort > ushort2; +typedef vtype3 < ushort > ushort3; +typedef vtype4 < ushort > ushort4; +typedef vtype2 < long >long2; +typedef vtype3 < long >long3; +typedef vtype4 < long >long4; +typedef vtype2 < ulong > ulong2; +typedef vtype3 < ulong > ulong3; +typedef vtype4 < ulong > ulong4; +static inline float2 operator+(float2 p, float2 q) +{ + return float2(p.x + q.x, p.y + q.y); +} +static inline float3 operator+(float3 p, float3 q) +{ + return float3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline float4 operator+(float4 p, float4 q) +{ + return float4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline float2 operator+(float2 p, float q) +{ + return float2(p.x + q, p.y + q); +} +static inline float3 operator+(float3 p, float q) +{ + return float3(p.x + q, p.y + q, p.z + q); +} +static inline float4 operator+(float4 p, float q) +{ + return float4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline float2 operator+(float p, float2 q) +{ + return float2(p + q.x, p + q.y); +} +static inline float3 operator+(float p, float3 q) +{ + return float3(p + q.x, p + q.y, p + q.z); +} +static inline float4 operator+(float p, float4 q) +{ + return float4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline double2 operator+(double2 p, double2 q) +{ + return double2(p.x + q.x, p.y + q.y); +} +static inline double3 operator+(double3 p, double3 q) +{ + return double3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline double4 operator+(double4 p, double4 q) +{ + return double4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline double2 operator+(double2 p, double q) +{ + return double2(p.x + q, p.y + q); +} +static inline double3 operator+(double3 p, double q) +{ + return double3(p.x + q, p.y + q, p.z + q); +} +static inline double4 operator+(double4 p, double q) +{ + return double4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline double2 operator+(double p, double2 q) +{ + return double2(p + q.x, p + q.y); +} +static inline double3 operator+(double p, double3 q) +{ + return double3(p + q.x, p + q.y, p + q.z); +} +static inline double4 operator+(double p, double4 q) +{ + return double4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline int2 operator+(int2 p, int2 q) +{ + return int2(p.x + q.x, p.y + q.y); +} +static inline int3 operator+(int3 p, int3 q) +{ + return int3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline int4 operator+(int4 p, int4 q) +{ + return int4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline int2 operator+(int2 p, int q) +{ + return int2(p.x + q, p.y + q); +} +static inline int3 operator+(int3 p, int q) +{ + return int3(p.x + q, p.y + q, p.z + q); +} +static inline int4 operator+(int4 p, int q) +{ + return int4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline int2 operator+(int p, int2 q) +{ + return int2(p + q.x, p + q.y); +} +static inline int3 operator+(int p, int3 q) +{ + return int3(p + q.x, p + q.y, p + q.z); +} +static inline int4 operator+(int p, int4 q) +{ + return int4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline uint2 operator+(uint2 p, uint2 q) +{ + return uint2(p.x + q.x, p.y + q.y); +} +static inline uint3 operator+(uint3 p, uint3 q) +{ + return uint3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline uint4 operator+(uint4 p, uint4 q) +{ + return uint4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline uint2 operator+(uint2 p, uint q) +{ + return uint2(p.x + q, p.y + q); +} +static inline uint3 operator+(uint3 p, uint q) +{ + return uint3(p.x + q, p.y + q, p.z + q); +} +static inline uint4 operator+(uint4 p, uint q) +{ + return uint4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline uint2 operator+(uint p, uint2 q) +{ + return uint2(p + q.x, p + q.y); +} +static inline uint3 operator+(uint p, uint3 q) +{ + return uint3(p + q.x, p + q.y, p + q.z); +} +static inline uint4 operator+(uint p, uint4 q) +{ + return uint4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline short2 operator+(short2 p, short2 q) +{ + return short2(p.x + q.x, p.y + q.y); +} +static inline short3 operator+(short3 p, short3 q) +{ + return short3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline short4 operator+(short4 p, short4 q) +{ + return short4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline short2 operator+(short2 p, short q) +{ + return short2(p.x + q, p.y + q); +} +static inline short3 operator+(short3 p, short q) +{ + return short3(p.x + q, p.y + q, p.z + q); +} +static inline short4 operator+(short4 p, short q) +{ + return short4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline short2 operator+(short p, short2 q) +{ + return short2(p + q.x, p + q.y); +} +static inline short3 operator+(short p, short3 q) +{ + return short3(p + q.x, p + q.y, p + q.z); +} +static inline short4 operator+(short p, short4 q) +{ + return short4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline ushort2 operator+(ushort2 p, ushort2 q) +{ + return ushort2(p.x + q.x, p.y + q.y); +} +static inline ushort3 operator+(ushort3 p, ushort3 q) +{ + return ushort3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline ushort4 operator+(ushort4 p, ushort4 q) +{ + return ushort4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline ushort2 operator+(ushort2 p, ushort q) +{ + return ushort2(p.x + q, p.y + q); +} +static inline ushort3 operator+(ushort3 p, ushort q) +{ + return ushort3(p.x + q, p.y + q, p.z + q); +} +static inline ushort4 operator+(ushort4 p, ushort q) +{ + return ushort4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline ushort2 operator+(ushort p, ushort2 q) +{ + return ushort2(p + q.x, p + q.y); +} +static inline ushort3 operator+(ushort p, ushort3 q) +{ + return ushort3(p + q.x, p + q.y, p + q.z); +} +static inline ushort4 operator+(ushort p, ushort4 q) +{ + return ushort4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline long2 operator+(long2 p, long2 q) +{ + return long2(p.x + q.x, p.y + q.y); +} +static inline long3 operator+(long3 p, long3 q) +{ + return long3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline long4 operator+(long4 p, long4 q) +{ + return long4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline long2 operator+(long2 p, long q) +{ + return long2(p.x + q, p.y + q); +} +static inline long3 operator+(long3 p, long q) +{ + return long3(p.x + q, p.y + q, p.z + q); +} +static inline long4 operator+(long4 p, long q) +{ + return long4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline long2 operator+(long p, long2 q) +{ + return long2(p + q.x, p + q.y); +} +static inline long3 operator+(long p, long3 q) +{ + return long3(p + q.x, p + q.y, p + q.z); +} +static inline long4 operator+(long p, long4 q) +{ + return long4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline ulong2 operator+(ulong2 p, ulong2 q) +{ + return ulong2(p.x + q.x, p.y + q.y); +} +static inline ulong3 operator+(ulong3 p, ulong3 q) +{ + return ulong3(p.x + q.x, p.y + q.y, p.z + q.z); +} +static inline ulong4 operator+(ulong4 p, ulong4 q) +{ + return ulong4(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w); +} +static inline ulong2 operator+(ulong2 p, ulong q) +{ + return ulong2(p.x + q, p.y + q); +} +static inline ulong3 operator+(ulong3 p, ulong q) +{ + return ulong3(p.x + q, p.y + q, p.z + q); +} +static inline ulong4 operator+(ulong4 p, ulong q) +{ + return ulong4(p.x + q, p.y + q, p.z + q, p.w + q); +} +static inline ulong2 operator+(ulong p, ulong2 q) +{ + return ulong2(p + q.x, p + q.y); +} +static inline ulong3 operator+(ulong p, ulong3 q) +{ + return ulong3(p + q.x, p + q.y, p + q.z); +} +static inline ulong4 operator+(ulong p, ulong4 q) +{ + return ulong4(p + q.x, p + q.y, p + q.z, p + q.w); +} +static inline float2 operator-(float2 p, float2 q) +{ + return float2(p.x - q.x, p.y - q.y); +} +static inline float3 operator-(float3 p, float3 q) +{ + return float3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline float4 operator-(float4 p, float4 q) +{ + return float4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline float2 operator-(float2 p, float q) +{ + return float2(p.x - q, p.y - q); +} +static inline float3 operator-(float3 p, float q) +{ + return float3(p.x - q, p.y - q, p.z - q); +} +static inline float4 operator-(float4 p, float q) +{ + return float4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline float2 operator-(float p, float2 q) +{ + return float2(p - q.x, p - q.y); +} +static inline float3 operator-(float p, float3 q) +{ + return float3(p - q.x, p - q.y, p - q.z); +} +static inline float4 operator-(float p, float4 q) +{ + return float4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline double2 operator-(double2 p, double2 q) +{ + return double2(p.x - q.x, p.y - q.y); +} +static inline double3 operator-(double3 p, double3 q) +{ + return double3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline double4 operator-(double4 p, double4 q) +{ + return double4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline double2 operator-(double2 p, double q) +{ + return double2(p.x - q, p.y - q); +} +static inline double3 operator-(double3 p, double q) +{ + return double3(p.x - q, p.y - q, p.z - q); +} +static inline double4 operator-(double4 p, double q) +{ + return double4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline double2 operator-(double p, double2 q) +{ + return double2(p - q.x, p - q.y); +} +static inline double3 operator-(double p, double3 q) +{ + return double3(p - q.x, p - q.y, p - q.z); +} +static inline double4 operator-(double p, double4 q) +{ + return double4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline int2 operator-(int2 p, int2 q) +{ + return int2(p.x - q.x, p.y - q.y); +} +static inline int3 operator-(int3 p, int3 q) +{ + return int3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline int4 operator-(int4 p, int4 q) +{ + return int4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline int2 operator-(int2 p, int q) +{ + return int2(p.x - q, p.y - q); +} +static inline int3 operator-(int3 p, int q) +{ + return int3(p.x - q, p.y - q, p.z - q); +} +static inline int4 operator-(int4 p, int q) +{ + return int4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline int2 operator-(int p, int2 q) +{ + return int2(p - q.x, p - q.y); +} +static inline int3 operator-(int p, int3 q) +{ + return int3(p - q.x, p - q.y, p - q.z); +} +static inline int4 operator-(int p, int4 q) +{ + return int4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline uint2 operator-(uint2 p, uint2 q) +{ + return uint2(p.x - q.x, p.y - q.y); +} +static inline uint3 operator-(uint3 p, uint3 q) +{ + return uint3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline uint4 operator-(uint4 p, uint4 q) +{ + return uint4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline uint2 operator-(uint2 p, uint q) +{ + return uint2(p.x - q, p.y - q); +} +static inline uint3 operator-(uint3 p, uint q) +{ + return uint3(p.x - q, p.y - q, p.z - q); +} +static inline uint4 operator-(uint4 p, uint q) +{ + return uint4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline uint2 operator-(uint p, uint2 q) +{ + return uint2(p - q.x, p - q.y); +} +static inline uint3 operator-(uint p, uint3 q) +{ + return uint3(p - q.x, p - q.y, p - q.z); +} +static inline uint4 operator-(uint p, uint4 q) +{ + return uint4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline short2 operator-(short2 p, short2 q) +{ + return short2(p.x - q.x, p.y - q.y); +} +static inline short3 operator-(short3 p, short3 q) +{ + return short3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline short4 operator-(short4 p, short4 q) +{ + return short4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline short2 operator-(short2 p, short q) +{ + return short2(p.x - q, p.y - q); +} +static inline short3 operator-(short3 p, short q) +{ + return short3(p.x - q, p.y - q, p.z - q); +} +static inline short4 operator-(short4 p, short q) +{ + return short4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline short2 operator-(short p, short2 q) +{ + return short2(p - q.x, p - q.y); +} +static inline short3 operator-(short p, short3 q) +{ + return short3(p - q.x, p - q.y, p - q.z); +} +static inline short4 operator-(short p, short4 q) +{ + return short4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline ushort2 operator-(ushort2 p, ushort2 q) +{ + return ushort2(p.x - q.x, p.y - q.y); +} +static inline ushort3 operator-(ushort3 p, ushort3 q) +{ + return ushort3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline ushort4 operator-(ushort4 p, ushort4 q) +{ + return ushort4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline ushort2 operator-(ushort2 p, ushort q) +{ + return ushort2(p.x - q, p.y - q); +} +static inline ushort3 operator-(ushort3 p, ushort q) +{ + return ushort3(p.x - q, p.y - q, p.z - q); +} +static inline ushort4 operator-(ushort4 p, ushort q) +{ + return ushort4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline ushort2 operator-(ushort p, ushort2 q) +{ + return ushort2(p - q.x, p - q.y); +} +static inline ushort3 operator-(ushort p, ushort3 q) +{ + return ushort3(p - q.x, p - q.y, p - q.z); +} +static inline ushort4 operator-(ushort p, ushort4 q) +{ + return ushort4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline long2 operator-(long2 p, long2 q) +{ + return long2(p.x - q.x, p.y - q.y); +} +static inline long3 operator-(long3 p, long3 q) +{ + return long3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline long4 operator-(long4 p, long4 q) +{ + return long4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline long2 operator-(long2 p, long q) +{ + return long2(p.x - q, p.y - q); +} +static inline long3 operator-(long3 p, long q) +{ + return long3(p.x - q, p.y - q, p.z - q); +} +static inline long4 operator-(long4 p, long q) +{ + return long4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline long2 operator-(long p, long2 q) +{ + return long2(p - q.x, p - q.y); +} +static inline long3 operator-(long p, long3 q) +{ + return long3(p - q.x, p - q.y, p - q.z); +} +static inline long4 operator-(long p, long4 q) +{ + return long4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline ulong2 operator-(ulong2 p, ulong2 q) +{ + return ulong2(p.x - q.x, p.y - q.y); +} +static inline ulong3 operator-(ulong3 p, ulong3 q) +{ + return ulong3(p.x - q.x, p.y - q.y, p.z - q.z); +} +static inline ulong4 operator-(ulong4 p, ulong4 q) +{ + return ulong4(p.x - q.x, p.y - q.y, p.z - q.z, p.w - q.w); +} +static inline ulong2 operator-(ulong2 p, ulong q) +{ + return ulong2(p.x - q, p.y - q); +} +static inline ulong3 operator-(ulong3 p, ulong q) +{ + return ulong3(p.x - q, p.y - q, p.z - q); +} +static inline ulong4 operator-(ulong4 p, ulong q) +{ + return ulong4(p.x - q, p.y - q, p.z - q, p.w - q); +} +static inline ulong2 operator-(ulong p, ulong2 q) +{ + return ulong2(p - q.x, p - q.y); +} +static inline ulong3 operator-(ulong p, ulong3 q) +{ + return ulong3(p - q.x, p - q.y, p - q.z); +} +static inline ulong4 operator-(ulong p, ulong4 q) +{ + return ulong4(p - q.x, p - q.y, p - q.z, p - q.w); +} +static inline float2 operator*(float2 p, float2 q) +{ + return float2(p.x * q.x, p.y * q.y); +} +static inline float3 operator*(float3 p, float3 q) +{ + return float3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline float4 operator*(float4 p, float4 q) +{ + return float4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline float2 operator*(float2 p, float q) +{ + return float2(p.x * q, p.y * q); +} +static inline float3 operator*(float3 p, float q) +{ + return float3(p.x * q, p.y * q, p.z * q); +} +static inline float4 operator*(float4 p, float q) +{ + return float4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline float2 operator*(float p, float2 q) +{ + return float2(p * q.x, p * q.y); +} +static inline float3 operator*(float p, float3 q) +{ + return float3(p * q.x, p * q.y, p * q.z); +} +static inline float4 operator*(float p, float4 q) +{ + return float4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline double2 operator*(double2 p, double2 q) +{ + return double2(p.x * q.x, p.y * q.y); +} +static inline double3 operator*(double3 p, double3 q) +{ + return double3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline double4 operator*(double4 p, double4 q) +{ + return double4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline double2 operator*(double2 p, double q) +{ + return double2(p.x * q, p.y * q); +} +static inline double3 operator*(double3 p, double q) +{ + return double3(p.x * q, p.y * q, p.z * q); +} +static inline double4 operator*(double4 p, double q) +{ + return double4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline double2 operator*(double p, double2 q) +{ + return double2(p * q.x, p * q.y); +} +static inline double3 operator*(double p, double3 q) +{ + return double3(p * q.x, p * q.y, p * q.z); +} +static inline double4 operator*(double p, double4 q) +{ + return double4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline int2 operator*(int2 p, int2 q) +{ + return int2(p.x * q.x, p.y * q.y); +} +static inline int3 operator*(int3 p, int3 q) +{ + return int3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline int4 operator*(int4 p, int4 q) +{ + return int4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline int2 operator*(int2 p, int q) +{ + return int2(p.x * q, p.y * q); +} +static inline int3 operator*(int3 p, int q) +{ + return int3(p.x * q, p.y * q, p.z * q); +} +static inline int4 operator*(int4 p, int q) +{ + return int4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline int2 operator*(int p, int2 q) +{ + return int2(p * q.x, p * q.y); +} +static inline int3 operator*(int p, int3 q) +{ + return int3(p * q.x, p * q.y, p * q.z); +} +static inline int4 operator*(int p, int4 q) +{ + return int4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline uint2 operator*(uint2 p, uint2 q) +{ + return uint2(p.x * q.x, p.y * q.y); +} +static inline uint3 operator*(uint3 p, uint3 q) +{ + return uint3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline uint4 operator*(uint4 p, uint4 q) +{ + return uint4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline uint2 operator*(uint2 p, uint q) +{ + return uint2(p.x * q, p.y * q); +} +static inline uint3 operator*(uint3 p, uint q) +{ + return uint3(p.x * q, p.y * q, p.z * q); +} +static inline uint4 operator*(uint4 p, uint q) +{ + return uint4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline uint2 operator*(uint p, uint2 q) +{ + return uint2(p * q.x, p * q.y); +} +static inline uint3 operator*(uint p, uint3 q) +{ + return uint3(p * q.x, p * q.y, p * q.z); +} +static inline uint4 operator*(uint p, uint4 q) +{ + return uint4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline short2 operator*(short2 p, short2 q) +{ + return short2(p.x * q.x, p.y * q.y); +} +static inline short3 operator*(short3 p, short3 q) +{ + return short3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline short4 operator*(short4 p, short4 q) +{ + return short4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline short2 operator*(short2 p, short q) +{ + return short2(p.x * q, p.y * q); +} +static inline short3 operator*(short3 p, short q) +{ + return short3(p.x * q, p.y * q, p.z * q); +} +static inline short4 operator*(short4 p, short q) +{ + return short4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline short2 operator*(short p, short2 q) +{ + return short2(p * q.x, p * q.y); +} +static inline short3 operator*(short p, short3 q) +{ + return short3(p * q.x, p * q.y, p * q.z); +} +static inline short4 operator*(short p, short4 q) +{ + return short4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline ushort2 operator*(ushort2 p, ushort2 q) +{ + return ushort2(p.x * q.x, p.y * q.y); +} +static inline ushort3 operator*(ushort3 p, ushort3 q) +{ + return ushort3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline ushort4 operator*(ushort4 p, ushort4 q) +{ + return ushort4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline ushort2 operator*(ushort2 p, ushort q) +{ + return ushort2(p.x * q, p.y * q); +} +static inline ushort3 operator*(ushort3 p, ushort q) +{ + return ushort3(p.x * q, p.y * q, p.z * q); +} +static inline ushort4 operator*(ushort4 p, ushort q) +{ + return ushort4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline ushort2 operator*(ushort p, ushort2 q) +{ + return ushort2(p * q.x, p * q.y); +} +static inline ushort3 operator*(ushort p, ushort3 q) +{ + return ushort3(p * q.x, p * q.y, p * q.z); +} +static inline ushort4 operator*(ushort p, ushort4 q) +{ + return ushort4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline long2 operator*(long2 p, long2 q) +{ + return long2(p.x * q.x, p.y * q.y); +} +static inline long3 operator*(long3 p, long3 q) +{ + return long3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline long4 operator*(long4 p, long4 q) +{ + return long4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline long2 operator*(long2 p, long q) +{ + return long2(p.x * q, p.y * q); +} +static inline long3 operator*(long3 p, long q) +{ + return long3(p.x * q, p.y * q, p.z * q); +} +static inline long4 operator*(long4 p, long q) +{ + return long4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline long2 operator*(long p, long2 q) +{ + return long2(p * q.x, p * q.y); +} +static inline long3 operator*(long p, long3 q) +{ + return long3(p * q.x, p * q.y, p * q.z); +} +static inline long4 operator*(long p, long4 q) +{ + return long4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline ulong2 operator*(ulong2 p, ulong2 q) +{ + return ulong2(p.x * q.x, p.y * q.y); +} +static inline ulong3 operator*(ulong3 p, ulong3 q) +{ + return ulong3(p.x * q.x, p.y * q.y, p.z * q.z); +} +static inline ulong4 operator*(ulong4 p, ulong4 q) +{ + return ulong4(p.x * q.x, p.y * q.y, p.z * q.z, p.w * q.w); +} +static inline ulong2 operator*(ulong2 p, ulong q) +{ + return ulong2(p.x * q, p.y * q); +} +static inline ulong3 operator*(ulong3 p, ulong q) +{ + return ulong3(p.x * q, p.y * q, p.z * q); +} +static inline ulong4 operator*(ulong4 p, ulong q) +{ + return ulong4(p.x * q, p.y * q, p.z * q, p.w * q); +} +static inline ulong2 operator*(ulong p, ulong2 q) +{ + return ulong2(p * q.x, p * q.y); +} +static inline ulong3 operator*(ulong p, ulong3 q) +{ + return ulong3(p * q.x, p * q.y, p * q.z); +} +static inline ulong4 operator*(ulong p, ulong4 q) +{ + return ulong4(p * q.x, p * q.y, p * q.z, p * q.w); +} +static inline float2 operator/(float2 p, float2 q) +{ + return float2(p.x / q.x, p.y / q.y); +} +static inline float3 operator/(float3 p, float3 q) +{ + return float3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline float4 operator/(float4 p, float4 q) +{ + return float4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline float2 operator/(float2 p, float q) +{ + return float2(p.x / q, p.y / q); +} +static inline float3 operator/(float3 p, float q) +{ + return float3(p.x / q, p.y / q, p.z / q); +} +static inline float4 operator/(float4 p, float q) +{ + return float4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline float2 operator/(float p, float2 q) +{ + return float2(p / q.x, p / q.y); +} +static inline float3 operator/(float p, float3 q) +{ + return float3(p / q.x, p / q.y, p / q.z); +} +static inline float4 operator/(float p, float4 q) +{ + return float4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline double2 operator/(double2 p, double2 q) +{ + return double2(p.x / q.x, p.y / q.y); +} +static inline double3 operator/(double3 p, double3 q) +{ + return double3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline double4 operator/(double4 p, double4 q) +{ + return double4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline double2 operator/(double2 p, double q) +{ + return double2(p.x / q, p.y / q); +} +static inline double3 operator/(double3 p, double q) +{ + return double3(p.x / q, p.y / q, p.z / q); +} +static inline double4 operator/(double4 p, double q) +{ + return double4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline double2 operator/(double p, double2 q) +{ + return double2(p / q.x, p / q.y); +} +static inline double3 operator/(double p, double3 q) +{ + return double3(p / q.x, p / q.y, p / q.z); +} +static inline double4 operator/(double p, double4 q) +{ + return double4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline int2 operator/(int2 p, int2 q) +{ + return int2(p.x / q.x, p.y / q.y); +} +static inline int3 operator/(int3 p, int3 q) +{ + return int3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline int4 operator/(int4 p, int4 q) +{ + return int4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline int2 operator/(int2 p, int q) +{ + return int2(p.x / q, p.y / q); +} +static inline int3 operator/(int3 p, int q) +{ + return int3(p.x / q, p.y / q, p.z / q); +} +static inline int4 operator/(int4 p, int q) +{ + return int4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline int2 operator/(int p, int2 q) +{ + return int2(p / q.x, p / q.y); +} +static inline int3 operator/(int p, int3 q) +{ + return int3(p / q.x, p / q.y, p / q.z); +} +static inline int4 operator/(int p, int4 q) +{ + return int4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline uint2 operator/(uint2 p, uint2 q) +{ + return uint2(p.x / q.x, p.y / q.y); +} +static inline uint3 operator/(uint3 p, uint3 q) +{ + return uint3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline uint4 operator/(uint4 p, uint4 q) +{ + return uint4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline uint2 operator/(uint2 p, uint q) +{ + return uint2(p.x / q, p.y / q); +} +static inline uint3 operator/(uint3 p, uint q) +{ + return uint3(p.x / q, p.y / q, p.z / q); +} +static inline uint4 operator/(uint4 p, uint q) +{ + return uint4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline uint2 operator/(uint p, uint2 q) +{ + return uint2(p / q.x, p / q.y); +} +static inline uint3 operator/(uint p, uint3 q) +{ + return uint3(p / q.x, p / q.y, p / q.z); +} +static inline uint4 operator/(uint p, uint4 q) +{ + return uint4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline short2 operator/(short2 p, short2 q) +{ + return short2(p.x / q.x, p.y / q.y); +} +static inline short3 operator/(short3 p, short3 q) +{ + return short3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline short4 operator/(short4 p, short4 q) +{ + return short4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline short2 operator/(short2 p, short q) +{ + return short2(p.x / q, p.y / q); +} +static inline short3 operator/(short3 p, short q) +{ + return short3(p.x / q, p.y / q, p.z / q); +} +static inline short4 operator/(short4 p, short q) +{ + return short4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline short2 operator/(short p, short2 q) +{ + return short2(p / q.x, p / q.y); +} +static inline short3 operator/(short p, short3 q) +{ + return short3(p / q.x, p / q.y, p / q.z); +} +static inline short4 operator/(short p, short4 q) +{ + return short4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline ushort2 operator/(ushort2 p, ushort2 q) +{ + return ushort2(p.x / q.x, p.y / q.y); +} +static inline ushort3 operator/(ushort3 p, ushort3 q) +{ + return ushort3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline ushort4 operator/(ushort4 p, ushort4 q) +{ + return ushort4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline ushort2 operator/(ushort2 p, ushort q) +{ + return ushort2(p.x / q, p.y / q); +} +static inline ushort3 operator/(ushort3 p, ushort q) +{ + return ushort3(p.x / q, p.y / q, p.z / q); +} +static inline ushort4 operator/(ushort4 p, ushort q) +{ + return ushort4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline ushort2 operator/(ushort p, ushort2 q) +{ + return ushort2(p / q.x, p / q.y); +} +static inline ushort3 operator/(ushort p, ushort3 q) +{ + return ushort3(p / q.x, p / q.y, p / q.z); +} +static inline ushort4 operator/(ushort p, ushort4 q) +{ + return ushort4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline long2 operator/(long2 p, long2 q) +{ + return long2(p.x / q.x, p.y / q.y); +} +static inline long3 operator/(long3 p, long3 q) +{ + return long3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline long4 operator/(long4 p, long4 q) +{ + return long4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline long2 operator/(long2 p, long q) +{ + return long2(p.x / q, p.y / q); +} +static inline long3 operator/(long3 p, long q) +{ + return long3(p.x / q, p.y / q, p.z / q); +} +static inline long4 operator/(long4 p, long q) +{ + return long4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline long2 operator/(long p, long2 q) +{ + return long2(p / q.x, p / q.y); +} +static inline long3 operator/(long p, long3 q) +{ + return long3(p / q.x, p / q.y, p / q.z); +} +static inline long4 operator/(long p, long4 q) +{ + return long4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline ulong2 operator/(ulong2 p, ulong2 q) +{ + return ulong2(p.x / q.x, p.y / q.y); +} +static inline ulong3 operator/(ulong3 p, ulong3 q) +{ + return ulong3(p.x / q.x, p.y / q.y, p.z / q.z); +} +static inline ulong4 operator/(ulong4 p, ulong4 q) +{ + return ulong4(p.x / q.x, p.y / q.y, p.z / q.z, p.w / q.w); +} +static inline ulong2 operator/(ulong2 p, ulong q) +{ + return ulong2(p.x / q, p.y / q); +} +static inline ulong3 operator/(ulong3 p, ulong q) +{ + return ulong3(p.x / q, p.y / q, p.z / q); +} +static inline ulong4 operator/(ulong4 p, ulong q) +{ + return ulong4(p.x / q, p.y / q, p.z / q, p.w / q); +} +static inline ulong2 operator/(ulong p, ulong2 q) +{ + return ulong2(p / q.x, p / q.y); +} +static inline ulong3 operator/(ulong p, ulong3 q) +{ + return ulong3(p / q.x, p / q.y, p / q.z); +} +static inline ulong4 operator/(ulong p, ulong4 q) +{ + return ulong4(p / q.x, p / q.y, p / q.z, p / q.w); +} +static inline int2 operator%(int2 p, int2 q) +{ + return int2(p.x % q.x, p.y % q.y); +} +static inline int3 operator%(int3 p, int3 q) +{ + return int3(p.x % q.x, p.y % q.y, p.z % q.z); +} +static inline int4 operator%(int4 p, int4 q) +{ + return int4(p.x % q.x, p.y % q.y, p.z % q.z, p.w % q.w); +} +static inline int2 operator%(int2 p, int q) +{ + return int2(p.x % q, p.y % q); +} +static inline int3 operator%(int3 p, int q) +{ + return int3(p.x % q, p.y % q, p.z % q); +} +static inline int4 operator%(int4 p, int q) +{ + return int4(p.x % q, p.y % q, p.z % q, p.w % q); +} +static inline int2 operator%(int p, int2 q) +{ + return int2(p % q.x, p % q.y); +} +static inline int3 operator%(int p, int3 q) +{ + return int3(p % q.x, p % q.y, p % q.z); +} +static inline int4 operator%(int p, int4 q) +{ + return int4(p % q.x, p % q.y, p % q.z, p % q.w); +} +static inline uint2 operator%(uint2 p, uint2 q) +{ + return uint2(p.x % q.x, p.y % q.y); +} +static inline uint3 operator%(uint3 p, uint3 q) +{ + return uint3(p.x % q.x, p.y % q.y, p.z % q.z); +} +static inline uint4 operator%(uint4 p, uint4 q) +{ + return uint4(p.x % q.x, p.y % q.y, p.z % q.z, p.w % q.w); +} +static inline uint2 operator%(uint2 p, uint q) +{ + return uint2(p.x % q, p.y % q); +} +static inline uint3 operator%(uint3 p, uint q) +{ + return uint3(p.x % q, p.y % q, p.z % q); +} +static inline uint4 operator%(uint4 p, uint q) +{ + return uint4(p.x % q, p.y % q, p.z % q, p.w % q); +} +static inline uint2 operator%(uint p, uint2 q) +{ + return uint2(p % q.x, p % q.y); +} +static inline uint3 operator%(uint p, uint3 q) +{ + return uint3(p % q.x, p % q.y, p % q.z); +} +static inline uint4 operator%(uint p, uint4 q) +{ + return uint4(p % q.x, p % q.y, p % q.z, p % q.w); +} +static inline short2 operator%(short2 p, short2 q) +{ + return short2(p.x % q.x, p.y % q.y); +} +static inline short3 operator%(short3 p, short3 q) +{ + return short3(p.x % q.x, p.y % q.y, p.z % q.z); +} +static inline short4 operator%(short4 p, short4 q) +{ + return short4(p.x % q.x, p.y % q.y, p.z % q.z, p.w % q.w); +} +static inline short2 operator%(short2 p, short q) +{ + return short2(p.x % q, p.y % q); +} +static inline short3 operator%(short3 p, short q) +{ + return short3(p.x % q, p.y % q, p.z % q); +} +static inline short4 operator%(short4 p, short q) +{ + return short4(p.x % q, p.y % q, p.z % q, p.w % q); +} +static inline short2 operator%(short p, short2 q) +{ + return short2(p % q.x, p % q.y); +} +static inline short3 operator%(short p, short3 q) +{ + return short3(p % q.x, p % q.y, p % q.z); +} +static inline short4 operator%(short p, short4 q) +{ + return short4(p % q.x, p % q.y, p % q.z, p % q.w); +} +static inline ushort2 operator%(ushort2 p, ushort2 q) +{ + return ushort2(p.x % q.x, p.y % q.y); +} +static inline ushort3 operator%(ushort3 p, ushort3 q) +{ + return ushort3(p.x % q.x, p.y % q.y, p.z % q.z); +} +static inline ushort4 operator%(ushort4 p, ushort4 q) +{ + return ushort4(p.x % q.x, p.y % q.y, p.z % q.z, p.w % q.w); +} +static inline ushort2 operator%(ushort2 p, ushort q) +{ + return ushort2(p.x % q, p.y % q); +} +static inline ushort3 operator%(ushort3 p, ushort q) +{ + return ushort3(p.x % q, p.y % q, p.z % q); +} +static inline ushort4 operator%(ushort4 p, ushort q) +{ + return ushort4(p.x % q, p.y % q, p.z % q, p.w % q); +} +static inline ushort2 operator%(ushort p, ushort2 q) +{ + return ushort2(p % q.x, p % q.y); +} +static inline ushort3 operator%(ushort p, ushort3 q) +{ + return ushort3(p % q.x, p % q.y, p % q.z); +} +static inline ushort4 operator%(ushort p, ushort4 q) +{ + return ushort4(p % q.x, p % q.y, p % q.z, p % q.w); +} +static inline long2 operator%(long2 p, long2 q) +{ + return long2(p.x % q.x, p.y % q.y); +} +static inline long3 operator%(long3 p, long3 q) +{ + return long3(p.x % q.x, p.y % q.y, p.z % q.z); +} +static inline long4 operator%(long4 p, long4 q) +{ + return long4(p.x % q.x, p.y % q.y, p.z % q.z, p.w % q.w); +} +static inline long2 operator%(long2 p, long q) +{ + return long2(p.x % q, p.y % q); +} +static inline long3 operator%(long3 p, long q) +{ + return long3(p.x % q, p.y % q, p.z % q); +} +static inline long4 operator%(long4 p, long q) +{ + return long4(p.x % q, p.y % q, p.z % q, p.w % q); +} +static inline long2 operator%(long p, long2 q) +{ + return long2(p % q.x, p % q.y); +} +static inline long3 operator%(long p, long3 q) +{ + return long3(p % q.x, p % q.y, p % q.z); +} +static inline long4 operator%(long p, long4 q) +{ + return long4(p % q.x, p % q.y, p % q.z, p % q.w); +} +static inline ulong2 operator%(ulong2 p, ulong2 q) +{ + return ulong2(p.x % q.x, p.y % q.y); +} +static inline ulong3 operator%(ulong3 p, ulong3 q) +{ + return ulong3(p.x % q.x, p.y % q.y, p.z % q.z); +} +static inline ulong4 operator%(ulong4 p, ulong4 q) +{ + return ulong4(p.x % q.x, p.y % q.y, p.z % q.z, p.w % q.w); +} +static inline ulong2 operator%(ulong2 p, ulong q) +{ + return ulong2(p.x % q, p.y % q); +} +static inline ulong3 operator%(ulong3 p, ulong q) +{ + return ulong3(p.x % q, p.y % q, p.z % q); +} +static inline ulong4 operator%(ulong4 p, ulong q) +{ + return ulong4(p.x % q, p.y % q, p.z % q, p.w % q); +} +static inline ulong2 operator%(ulong p, ulong2 q) +{ + return ulong2(p % q.x, p % q.y); +} +static inline ulong3 operator%(ulong p, ulong3 q) +{ + return ulong3(p % q.x, p % q.y, p % q.z); +} +static inline ulong4 operator%(ulong p, ulong4 q) +{ + return ulong4(p % q.x, p % q.y, p % q.z, p % q.w); +} +static inline int2 operator&(int2 p, int2 q) +{ + return int2(p.x & q.x, p.y & q.y); +} +static inline int3 operator&(int3 p, int3 q) +{ + return int3(p.x & q.x, p.y & q.y, p.z & q.z); +} +static inline int4 operator&(int4 p, int4 q) +{ + return int4(p.x & q.x, p.y & q.y, p.z & q.z, p.w & q.w); +} +static inline int2 operator&(int2 p, int q) +{ + return int2(p.x & q, p.y & q); +} +static inline int3 operator&(int3 p, int q) +{ + return int3(p.x & q, p.y & q, p.z & q); +} +static inline int4 operator&(int4 p, int q) +{ + return int4(p.x & q, p.y & q, p.z & q, p.w & q); +} +static inline int2 operator&(int p, int2 q) +{ + return int2(p & q.x, p & q.y); +} +static inline int3 operator&(int p, int3 q) +{ + return int3(p & q.x, p & q.y, p & q.z); +} +static inline int4 operator&(int p, int4 q) +{ + return int4(p & q.x, p & q.y, p & q.z, p & q.w); +} +static inline uint2 operator&(uint2 p, uint2 q) +{ + return uint2(p.x & q.x, p.y & q.y); +} +static inline uint3 operator&(uint3 p, uint3 q) +{ + return uint3(p.x & q.x, p.y & q.y, p.z & q.z); +} +static inline uint4 operator&(uint4 p, uint4 q) +{ + return uint4(p.x & q.x, p.y & q.y, p.z & q.z, p.w & q.w); +} +static inline uint2 operator&(uint2 p, uint q) +{ + return uint2(p.x & q, p.y & q); +} +static inline uint3 operator&(uint3 p, uint q) +{ + return uint3(p.x & q, p.y & q, p.z & q); +} +static inline uint4 operator&(uint4 p, uint q) +{ + return uint4(p.x & q, p.y & q, p.z & q, p.w & q); +} +static inline uint2 operator&(uint p, uint2 q) +{ + return uint2(p & q.x, p & q.y); +} +static inline uint3 operator&(uint p, uint3 q) +{ + return uint3(p & q.x, p & q.y, p & q.z); +} +static inline uint4 operator&(uint p, uint4 q) +{ + return uint4(p & q.x, p & q.y, p & q.z, p & q.w); +} +static inline short2 operator&(short2 p, short2 q) +{ + return short2(p.x & q.x, p.y & q.y); +} +static inline short3 operator&(short3 p, short3 q) +{ + return short3(p.x & q.x, p.y & q.y, p.z & q.z); +} +static inline short4 operator&(short4 p, short4 q) +{ + return short4(p.x & q.x, p.y & q.y, p.z & q.z, p.w & q.w); +} +static inline short2 operator&(short2 p, short q) +{ + return short2(p.x & q, p.y & q); +} +static inline short3 operator&(short3 p, short q) +{ + return short3(p.x & q, p.y & q, p.z & q); +} +static inline short4 operator&(short4 p, short q) +{ + return short4(p.x & q, p.y & q, p.z & q, p.w & q); +} +static inline short2 operator&(short p, short2 q) +{ + return short2(p & q.x, p & q.y); +} +static inline short3 operator&(short p, short3 q) +{ + return short3(p & q.x, p & q.y, p & q.z); +} +static inline short4 operator&(short p, short4 q) +{ + return short4(p & q.x, p & q.y, p & q.z, p & q.w); +} +static inline ushort2 operator&(ushort2 p, ushort2 q) +{ + return ushort2(p.x & q.x, p.y & q.y); +} +static inline ushort3 operator&(ushort3 p, ushort3 q) +{ + return ushort3(p.x & q.x, p.y & q.y, p.z & q.z); +} +static inline ushort4 operator&(ushort4 p, ushort4 q) +{ + return ushort4(p.x & q.x, p.y & q.y, p.z & q.z, p.w & q.w); +} +static inline ushort2 operator&(ushort2 p, ushort q) +{ + return ushort2(p.x & q, p.y & q); +} +static inline ushort3 operator&(ushort3 p, ushort q) +{ + return ushort3(p.x & q, p.y & q, p.z & q); +} +static inline ushort4 operator&(ushort4 p, ushort q) +{ + return ushort4(p.x & q, p.y & q, p.z & q, p.w & q); +} +static inline ushort2 operator&(ushort p, ushort2 q) +{ + return ushort2(p & q.x, p & q.y); +} +static inline ushort3 operator&(ushort p, ushort3 q) +{ + return ushort3(p & q.x, p & q.y, p & q.z); +} +static inline ushort4 operator&(ushort p, ushort4 q) +{ + return ushort4(p & q.x, p & q.y, p & q.z, p & q.w); +} +static inline long2 operator&(long2 p, long2 q) +{ + return long2(p.x & q.x, p.y & q.y); +} +static inline long3 operator&(long3 p, long3 q) +{ + return long3(p.x & q.x, p.y & q.y, p.z & q.z); +} +static inline long4 operator&(long4 p, long4 q) +{ + return long4(p.x & q.x, p.y & q.y, p.z & q.z, p.w & q.w); +} +static inline long2 operator&(long2 p, long q) +{ + return long2(p.x & q, p.y & q); +} +static inline long3 operator&(long3 p, long q) +{ + return long3(p.x & q, p.y & q, p.z & q); +} +static inline long4 operator&(long4 p, long q) +{ + return long4(p.x & q, p.y & q, p.z & q, p.w & q); +} +static inline long2 operator&(long p, long2 q) +{ + return long2(p & q.x, p & q.y); +} +static inline long3 operator&(long p, long3 q) +{ + return long3(p & q.x, p & q.y, p & q.z); +} +static inline long4 operator&(long p, long4 q) +{ + return long4(p & q.x, p & q.y, p & q.z, p & q.w); +} +static inline ulong2 operator&(ulong2 p, ulong2 q) +{ + return ulong2(p.x & q.x, p.y & q.y); +} +static inline ulong3 operator&(ulong3 p, ulong3 q) +{ + return ulong3(p.x & q.x, p.y & q.y, p.z & q.z); +} +static inline ulong4 operator&(ulong4 p, ulong4 q) +{ + return ulong4(p.x & q.x, p.y & q.y, p.z & q.z, p.w & q.w); +} +static inline ulong2 operator&(ulong2 p, ulong q) +{ + return ulong2(p.x & q, p.y & q); +} +static inline ulong3 operator&(ulong3 p, ulong q) +{ + return ulong3(p.x & q, p.y & q, p.z & q); +} +static inline ulong4 operator&(ulong4 p, ulong q) +{ + return ulong4(p.x & q, p.y & q, p.z & q, p.w & q); +} +static inline ulong2 operator&(ulong p, ulong2 q) +{ + return ulong2(p & q.x, p & q.y); +} +static inline ulong3 operator&(ulong p, ulong3 q) +{ + return ulong3(p & q.x, p & q.y, p & q.z); +} +static inline ulong4 operator&(ulong p, ulong4 q) +{ + return ulong4(p & q.x, p & q.y, p & q.z, p & q.w); +} +static inline int2 operator|(int2 p, int2 q) +{ + return int2(p.x | q.x, p.y | q.y); +} +static inline int3 operator|(int3 p, int3 q) +{ + return int3(p.x | q.x, p.y | q.y, p.z | q.z); +} +static inline int4 operator|(int4 p, int4 q) +{ + return int4(p.x | q.x, p.y | q.y, p.z | q.z, p.w | q.w); +} +static inline int2 operator|(int2 p, int q) +{ + return int2(p.x | q, p.y | q); +} +static inline int3 operator|(int3 p, int q) +{ + return int3(p.x | q, p.y | q, p.z | q); +} +static inline int4 operator|(int4 p, int q) +{ + return int4(p.x | q, p.y | q, p.z | q, p.w | q); +} +static inline int2 operator|(int p, int2 q) +{ + return int2(p | q.x, p | q.y); +} +static inline int3 operator|(int p, int3 q) +{ + return int3(p | q.x, p | q.y, p | q.z); +} +static inline int4 operator|(int p, int4 q) +{ + return int4(p | q.x, p | q.y, p | q.z, p | q.w); +} +static inline uint2 operator|(uint2 p, uint2 q) +{ + return uint2(p.x | q.x, p.y | q.y); +} +static inline uint3 operator|(uint3 p, uint3 q) +{ + return uint3(p.x | q.x, p.y | q.y, p.z | q.z); +} +static inline uint4 operator|(uint4 p, uint4 q) +{ + return uint4(p.x | q.x, p.y | q.y, p.z | q.z, p.w | q.w); +} +static inline uint2 operator|(uint2 p, uint q) +{ + return uint2(p.x | q, p.y | q); +} +static inline uint3 operator|(uint3 p, uint q) +{ + return uint3(p.x | q, p.y | q, p.z | q); +} +static inline uint4 operator|(uint4 p, uint q) +{ + return uint4(p.x | q, p.y | q, p.z | q, p.w | q); +} +static inline uint2 operator|(uint p, uint2 q) +{ + return uint2(p | q.x, p | q.y); +} +static inline uint3 operator|(uint p, uint3 q) +{ + return uint3(p | q.x, p | q.y, p | q.z); +} +static inline uint4 operator|(uint p, uint4 q) +{ + return uint4(p | q.x, p | q.y, p | q.z, p | q.w); +} +static inline short2 operator|(short2 p, short2 q) +{ + return short2(p.x | q.x, p.y | q.y); +} +static inline short3 operator|(short3 p, short3 q) +{ + return short3(p.x | q.x, p.y | q.y, p.z | q.z); +} +static inline short4 operator|(short4 p, short4 q) +{ + return short4(p.x | q.x, p.y | q.y, p.z | q.z, p.w | q.w); +} +static inline short2 operator|(short2 p, short q) +{ + return short2(p.x | q, p.y | q); +} +static inline short3 operator|(short3 p, short q) +{ + return short3(p.x | q, p.y | q, p.z | q); +} +static inline short4 operator|(short4 p, short q) +{ + return short4(p.x | q, p.y | q, p.z | q, p.w | q); +} +static inline short2 operator|(short p, short2 q) +{ + return short2(p | q.x, p | q.y); +} +static inline short3 operator|(short p, short3 q) +{ + return short3(p | q.x, p | q.y, p | q.z); +} +static inline short4 operator|(short p, short4 q) +{ + return short4(p | q.x, p | q.y, p | q.z, p | q.w); +} +static inline ushort2 operator|(ushort2 p, ushort2 q) +{ + return ushort2(p.x | q.x, p.y | q.y); +} +static inline ushort3 operator|(ushort3 p, ushort3 q) +{ + return ushort3(p.x | q.x, p.y | q.y, p.z | q.z); +} +static inline ushort4 operator|(ushort4 p, ushort4 q) +{ + return ushort4(p.x | q.x, p.y | q.y, p.z | q.z, p.w | q.w); +} +static inline ushort2 operator|(ushort2 p, ushort q) +{ + return ushort2(p.x | q, p.y | q); +} +static inline ushort3 operator|(ushort3 p, ushort q) +{ + return ushort3(p.x | q, p.y | q, p.z | q); +} +static inline ushort4 operator|(ushort4 p, ushort q) +{ + return ushort4(p.x | q, p.y | q, p.z | q, p.w | q); +} +static inline ushort2 operator|(ushort p, ushort2 q) +{ + return ushort2(p | q.x, p | q.y); +} +static inline ushort3 operator|(ushort p, ushort3 q) +{ + return ushort3(p | q.x, p | q.y, p | q.z); +} +static inline ushort4 operator|(ushort p, ushort4 q) +{ + return ushort4(p | q.x, p | q.y, p | q.z, p | q.w); +} +static inline long2 operator|(long2 p, long2 q) +{ + return long2(p.x | q.x, p.y | q.y); +} +static inline long3 operator|(long3 p, long3 q) +{ + return long3(p.x | q.x, p.y | q.y, p.z | q.z); +} +static inline long4 operator|(long4 p, long4 q) +{ + return long4(p.x | q.x, p.y | q.y, p.z | q.z, p.w | q.w); +} +static inline long2 operator|(long2 p, long q) +{ + return long2(p.x | q, p.y | q); +} +static inline long3 operator|(long3 p, long q) +{ + return long3(p.x | q, p.y | q, p.z | q); +} +static inline long4 operator|(long4 p, long q) +{ + return long4(p.x | q, p.y | q, p.z | q, p.w | q); +} +static inline long2 operator|(long p, long2 q) +{ + return long2(p | q.x, p | q.y); +} +static inline long3 operator|(long p, long3 q) +{ + return long3(p | q.x, p | q.y, p | q.z); +} +static inline long4 operator|(long p, long4 q) +{ + return long4(p | q.x, p | q.y, p | q.z, p | q.w); +} +static inline ulong2 operator|(ulong2 p, ulong2 q) +{ + return ulong2(p.x | q.x, p.y | q.y); +} +static inline ulong3 operator|(ulong3 p, ulong3 q) +{ + return ulong3(p.x | q.x, p.y | q.y, p.z | q.z); +} +static inline ulong4 operator|(ulong4 p, ulong4 q) +{ + return ulong4(p.x | q.x, p.y | q.y, p.z | q.z, p.w | q.w); +} +static inline ulong2 operator|(ulong2 p, ulong q) +{ + return ulong2(p.x | q, p.y | q); +} +static inline ulong3 operator|(ulong3 p, ulong q) +{ + return ulong3(p.x | q, p.y | q, p.z | q); +} +static inline ulong4 operator|(ulong4 p, ulong q) +{ + return ulong4(p.x | q, p.y | q, p.z | q, p.w | q); +} +static inline ulong2 operator|(ulong p, ulong2 q) +{ + return ulong2(p | q.x, p | q.y); +} +static inline ulong3 operator|(ulong p, ulong3 q) +{ + return ulong3(p | q.x, p | q.y, p | q.z); +} +static inline ulong4 operator|(ulong p, ulong4 q) +{ + return ulong4(p | q.x, p | q.y, p | q.z, p | q.w); +} +static inline int2 operator^(int2 p, int2 q) +{ + return int2(p.x ^ q.x, p.y ^ q.y); +} +static inline int3 operator^(int3 p, int3 q) +{ + return int3(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z); +} +static inline int4 operator^(int4 p, int4 q) +{ + return int4(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z, p.w ^ q.w); +} +static inline int2 operator^(int2 p, int q) +{ + return int2(p.x ^ q, p.y ^ q); +} +static inline int3 operator^(int3 p, int q) +{ + return int3(p.x ^ q, p.y ^ q, p.z ^ q); +} +static inline int4 operator^(int4 p, int q) +{ + return int4(p.x ^ q, p.y ^ q, p.z ^ q, p.w ^ q); +} +static inline int2 operator^(int p, int2 q) +{ + return int2(p ^ q.x, p ^ q.y); +} +static inline int3 operator^(int p, int3 q) +{ + return int3(p ^ q.x, p ^ q.y, p ^ q.z); +} +static inline int4 operator^(int p, int4 q) +{ + return int4(p ^ q.x, p ^ q.y, p ^ q.z, p ^ q.w); +} +static inline uint2 operator^(uint2 p, uint2 q) +{ + return uint2(p.x ^ q.x, p.y ^ q.y); +} +static inline uint3 operator^(uint3 p, uint3 q) +{ + return uint3(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z); +} +static inline uint4 operator^(uint4 p, uint4 q) +{ + return uint4(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z, p.w ^ q.w); +} +static inline uint2 operator^(uint2 p, uint q) +{ + return uint2(p.x ^ q, p.y ^ q); +} +static inline uint3 operator^(uint3 p, uint q) +{ + return uint3(p.x ^ q, p.y ^ q, p.z ^ q); +} +static inline uint4 operator^(uint4 p, uint q) +{ + return uint4(p.x ^ q, p.y ^ q, p.z ^ q, p.w ^ q); +} +static inline uint2 operator^(uint p, uint2 q) +{ + return uint2(p ^ q.x, p ^ q.y); +} +static inline uint3 operator^(uint p, uint3 q) +{ + return uint3(p ^ q.x, p ^ q.y, p ^ q.z); +} +static inline uint4 operator^(uint p, uint4 q) +{ + return uint4(p ^ q.x, p ^ q.y, p ^ q.z, p ^ q.w); +} +static inline short2 operator^(short2 p, short2 q) +{ + return short2(p.x ^ q.x, p.y ^ q.y); +} +static inline short3 operator^(short3 p, short3 q) +{ + return short3(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z); +} +static inline short4 operator^(short4 p, short4 q) +{ + return short4(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z, p.w ^ q.w); +} +static inline short2 operator^(short2 p, short q) +{ + return short2(p.x ^ q, p.y ^ q); +} +static inline short3 operator^(short3 p, short q) +{ + return short3(p.x ^ q, p.y ^ q, p.z ^ q); +} +static inline short4 operator^(short4 p, short q) +{ + return short4(p.x ^ q, p.y ^ q, p.z ^ q, p.w ^ q); +} +static inline short2 operator^(short p, short2 q) +{ + return short2(p ^ q.x, p ^ q.y); +} +static inline short3 operator^(short p, short3 q) +{ + return short3(p ^ q.x, p ^ q.y, p ^ q.z); +} +static inline short4 operator^(short p, short4 q) +{ + return short4(p ^ q.x, p ^ q.y, p ^ q.z, p ^ q.w); +} +static inline ushort2 operator^(ushort2 p, ushort2 q) +{ + return ushort2(p.x ^ q.x, p.y ^ q.y); +} +static inline ushort3 operator^(ushort3 p, ushort3 q) +{ + return ushort3(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z); +} +static inline ushort4 operator^(ushort4 p, ushort4 q) +{ + return ushort4(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z, p.w ^ q.w); +} +static inline ushort2 operator^(ushort2 p, ushort q) +{ + return ushort2(p.x ^ q, p.y ^ q); +} +static inline ushort3 operator^(ushort3 p, ushort q) +{ + return ushort3(p.x ^ q, p.y ^ q, p.z ^ q); +} +static inline ushort4 operator^(ushort4 p, ushort q) +{ + return ushort4(p.x ^ q, p.y ^ q, p.z ^ q, p.w ^ q); +} +static inline ushort2 operator^(ushort p, ushort2 q) +{ + return ushort2(p ^ q.x, p ^ q.y); +} +static inline ushort3 operator^(ushort p, ushort3 q) +{ + return ushort3(p ^ q.x, p ^ q.y, p ^ q.z); +} +static inline ushort4 operator^(ushort p, ushort4 q) +{ + return ushort4(p ^ q.x, p ^ q.y, p ^ q.z, p ^ q.w); +} +static inline long2 operator^(long2 p, long2 q) +{ + return long2(p.x ^ q.x, p.y ^ q.y); +} +static inline long3 operator^(long3 p, long3 q) +{ + return long3(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z); +} +static inline long4 operator^(long4 p, long4 q) +{ + return long4(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z, p.w ^ q.w); +} +static inline long2 operator^(long2 p, long q) +{ + return long2(p.x ^ q, p.y ^ q); +} +static inline long3 operator^(long3 p, long q) +{ + return long3(p.x ^ q, p.y ^ q, p.z ^ q); +} +static inline long4 operator^(long4 p, long q) +{ + return long4(p.x ^ q, p.y ^ q, p.z ^ q, p.w ^ q); +} +static inline long2 operator^(long p, long2 q) +{ + return long2(p ^ q.x, p ^ q.y); +} +static inline long3 operator^(long p, long3 q) +{ + return long3(p ^ q.x, p ^ q.y, p ^ q.z); +} +static inline long4 operator^(long p, long4 q) +{ + return long4(p ^ q.x, p ^ q.y, p ^ q.z, p ^ q.w); +} +static inline ulong2 operator^(ulong2 p, ulong2 q) +{ + return ulong2(p.x ^ q.x, p.y ^ q.y); +} +static inline ulong3 operator^(ulong3 p, ulong3 q) +{ + return ulong3(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z); +} +static inline ulong4 operator^(ulong4 p, ulong4 q) +{ + return ulong4(p.x ^ q.x, p.y ^ q.y, p.z ^ q.z, p.w ^ q.w); +} +static inline ulong2 operator^(ulong2 p, ulong q) +{ + return ulong2(p.x ^ q, p.y ^ q); +} +static inline ulong3 operator^(ulong3 p, ulong q) +{ + return ulong3(p.x ^ q, p.y ^ q, p.z ^ q); +} +static inline ulong4 operator^(ulong4 p, ulong q) +{ + return ulong4(p.x ^ q, p.y ^ q, p.z ^ q, p.w ^ q); +} +static inline ulong2 operator^(ulong p, ulong2 q) +{ + return ulong2(p ^ q.x, p ^ q.y); +} +static inline ulong3 operator^(ulong p, ulong3 q) +{ + return ulong3(p ^ q.x, p ^ q.y, p ^ q.z); +} +static inline ulong4 operator^(ulong p, ulong4 q) +{ + return ulong4(p ^ q.x, p ^ q.y, p ^ q.z, p ^ q.w); +} +static inline int2 operator<<(int2 p, int2 q) +{ + return int2(p.x << q.x, p.y << q.y); +} +static inline int3 operator<<(int3 p, int3 q) +{ + return int3(p.x << q.x, p.y << q.y, p.z << q.z); +} +static inline int4 operator<<(int4 p, int4 q) +{ + return int4(p.x << q.x, p.y << q.y, p.z << q.z, p.w << q.w); +} +static inline int2 operator<<(int2 p, int q) +{ + return int2(p.x << q, p.y << q); +} +static inline int3 operator<<(int3 p, int q) +{ + return int3(p.x << q, p.y << q, p.z << q); +} +static inline int4 operator<<(int4 p, int q) +{ + return int4(p.x << q, p.y << q, p.z << q, p.w << q); +} +static inline int2 operator<<(int p, int2 q) +{ + return int2(p << q.x, p << q.y); +} +static inline int3 operator<<(int p, int3 q) +{ + return int3(p << q.x, p << q.y, p << q.z); +} +static inline int4 operator<<(int p, int4 q) +{ + return int4(p << q.x, p << q.y, p << q.z, p << q.w); +} +static inline uint2 operator<<(uint2 p, uint2 q) +{ + return uint2(p.x << q.x, p.y << q.y); +} +static inline uint3 operator<<(uint3 p, uint3 q) +{ + return uint3(p.x << q.x, p.y << q.y, p.z << q.z); +} +static inline uint4 operator<<(uint4 p, uint4 q) +{ + return uint4(p.x << q.x, p.y << q.y, p.z << q.z, p.w << q.w); +} +static inline uint2 operator<<(uint2 p, uint q) +{ + return uint2(p.x << q, p.y << q); +} +static inline uint3 operator<<(uint3 p, uint q) +{ + return uint3(p.x << q, p.y << q, p.z << q); +} +static inline uint4 operator<<(uint4 p, uint q) +{ + return uint4(p.x << q, p.y << q, p.z << q, p.w << q); +} +static inline uint2 operator<<(uint p, uint2 q) +{ + return uint2(p << q.x, p << q.y); +} +static inline uint3 operator<<(uint p, uint3 q) +{ + return uint3(p << q.x, p << q.y, p << q.z); +} +static inline uint4 operator<<(uint p, uint4 q) +{ + return uint4(p << q.x, p << q.y, p << q.z, p << q.w); +} +static inline short2 operator<<(short2 p, short2 q) +{ + return short2(p.x << q.x, p.y << q.y); +} +static inline short3 operator<<(short3 p, short3 q) +{ + return short3(p.x << q.x, p.y << q.y, p.z << q.z); +} +static inline short4 operator<<(short4 p, short4 q) +{ + return short4(p.x << q.x, p.y << q.y, p.z << q.z, p.w << q.w); +} +static inline short2 operator<<(short2 p, short q) +{ + return short2(p.x << q, p.y << q); +} +static inline short3 operator<<(short3 p, short q) +{ + return short3(p.x << q, p.y << q, p.z << q); +} +static inline short4 operator<<(short4 p, short q) +{ + return short4(p.x << q, p.y << q, p.z << q, p.w << q); +} +static inline short2 operator<<(short p, short2 q) +{ + return short2(p << q.x, p << q.y); +} +static inline short3 operator<<(short p, short3 q) +{ + return short3(p << q.x, p << q.y, p << q.z); +} +static inline short4 operator<<(short p, short4 q) +{ + return short4(p << q.x, p << q.y, p << q.z, p << q.w); +} +static inline ushort2 operator<<(ushort2 p, ushort2 q) +{ + return ushort2(p.x << q.x, p.y << q.y); +} +static inline ushort3 operator<<(ushort3 p, ushort3 q) +{ + return ushort3(p.x << q.x, p.y << q.y, p.z << q.z); +} +static inline ushort4 operator<<(ushort4 p, ushort4 q) +{ + return ushort4(p.x << q.x, p.y << q.y, p.z << q.z, p.w << q.w); +} +static inline ushort2 operator<<(ushort2 p, ushort q) +{ + return ushort2(p.x << q, p.y << q); +} +static inline ushort3 operator<<(ushort3 p, ushort q) +{ + return ushort3(p.x << q, p.y << q, p.z << q); +} +static inline ushort4 operator<<(ushort4 p, ushort q) +{ + return ushort4(p.x << q, p.y << q, p.z << q, p.w << q); +} +static inline ushort2 operator<<(ushort p, ushort2 q) +{ + return ushort2(p << q.x, p << q.y); +} +static inline ushort3 operator<<(ushort p, ushort3 q) +{ + return ushort3(p << q.x, p << q.y, p << q.z); +} +static inline ushort4 operator<<(ushort p, ushort4 q) +{ + return ushort4(p << q.x, p << q.y, p << q.z, p << q.w); +} +static inline long2 operator<<(long2 p, long2 q) +{ + return long2(p.x << q.x, p.y << q.y); +} +static inline long3 operator<<(long3 p, long3 q) +{ + return long3(p.x << q.x, p.y << q.y, p.z << q.z); +} +static inline long4 operator<<(long4 p, long4 q) +{ + return long4(p.x << q.x, p.y << q.y, p.z << q.z, p.w << q.w); +} +static inline long2 operator<<(long2 p, long q) +{ + return long2(p.x << q, p.y << q); +} +static inline long3 operator<<(long3 p, long q) +{ + return long3(p.x << q, p.y << q, p.z << q); +} +static inline long4 operator<<(long4 p, long q) +{ + return long4(p.x << q, p.y << q, p.z << q, p.w << q); +} +static inline long2 operator<<(long p, long2 q) +{ + return long2(p << q.x, p << q.y); +} +static inline long3 operator<<(long p, long3 q) +{ + return long3(p << q.x, p << q.y, p << q.z); +} +static inline long4 operator<<(long p, long4 q) +{ + return long4(p << q.x, p << q.y, p << q.z, p << q.w); +} +static inline ulong2 operator<<(ulong2 p, ulong2 q) +{ + return ulong2(p.x << q.x, p.y << q.y); +} +static inline ulong3 operator<<(ulong3 p, ulong3 q) +{ + return ulong3(p.x << q.x, p.y << q.y, p.z << q.z); +} +static inline ulong4 operator<<(ulong4 p, ulong4 q) +{ + return ulong4(p.x << q.x, p.y << q.y, p.z << q.z, p.w << q.w); +} +static inline ulong2 operator<<(ulong2 p, ulong q) +{ + return ulong2(p.x << q, p.y << q); +} +static inline ulong3 operator<<(ulong3 p, ulong q) +{ + return ulong3(p.x << q, p.y << q, p.z << q); +} +static inline ulong4 operator<<(ulong4 p, ulong q) +{ + return ulong4(p.x << q, p.y << q, p.z << q, p.w << q); +} +static inline ulong2 operator<<(ulong p, ulong2 q) +{ + return ulong2(p << q.x, p << q.y); +} +static inline ulong3 operator<<(ulong p, ulong3 q) +{ + return ulong3(p << q.x, p << q.y, p << q.z); +} +static inline ulong4 operator<<(ulong p, ulong4 q) +{ + return ulong4(p << q.x, p << q.y, p << q.z, p << q.w); +} +static inline int2 operator>>(int2 p, int2 q) +{ + return int2(p.x >> q.x, p.y >> q.y); +} +static inline int3 operator>>(int3 p, int3 q) +{ + return int3(p.x >> q.x, p.y >> q.y, p.z >> q.z); +} +static inline int4 operator>>(int4 p, int4 q) +{ + return int4(p.x >> q.x, p.y >> q.y, p.z >> q.z, p.w >> q.w); +} +static inline int2 operator>>(int2 p, int q) +{ + return int2(p.x >> q, p.y >> q); +} +static inline int3 operator>>(int3 p, int q) +{ + return int3(p.x >> q, p.y >> q, p.z >> q); +} +static inline int4 operator>>(int4 p, int q) +{ + return int4(p.x >> q, p.y >> q, p.z >> q, p.w >> q); +} +static inline int2 operator>>(int p, int2 q) +{ + return int2(p >> q.x, p >> q.y); +} +static inline int3 operator>>(int p, int3 q) +{ + return int3(p >> q.x, p >> q.y, p >> q.z); +} +static inline int4 operator>>(int p, int4 q) +{ + return int4(p >> q.x, p >> q.y, p >> q.z, p >> q.w); +} +static inline uint2 operator>>(uint2 p, uint2 q) +{ + return uint2(p.x >> q.x, p.y >> q.y); +} +static inline uint3 operator>>(uint3 p, uint3 q) +{ + return uint3(p.x >> q.x, p.y >> q.y, p.z >> q.z); +} +static inline uint4 operator>>(uint4 p, uint4 q) +{ + return uint4(p.x >> q.x, p.y >> q.y, p.z >> q.z, p.w >> q.w); +} +static inline uint2 operator>>(uint2 p, uint q) +{ + return uint2(p.x >> q, p.y >> q); +} +static inline uint3 operator>>(uint3 p, uint q) +{ + return uint3(p.x >> q, p.y >> q, p.z >> q); +} +static inline uint4 operator>>(uint4 p, uint q) +{ + return uint4(p.x >> q, p.y >> q, p.z >> q, p.w >> q); +} +static inline uint2 operator>>(uint p, uint2 q) +{ + return uint2(p >> q.x, p >> q.y); +} +static inline uint3 operator>>(uint p, uint3 q) +{ + return uint3(p >> q.x, p >> q.y, p >> q.z); +} +static inline uint4 operator>>(uint p, uint4 q) +{ + return uint4(p >> q.x, p >> q.y, p >> q.z, p >> q.w); +} +static inline short2 operator>>(short2 p, short2 q) +{ + return short2(p.x >> q.x, p.y >> q.y); +} +static inline short3 operator>>(short3 p, short3 q) +{ + return short3(p.x >> q.x, p.y >> q.y, p.z >> q.z); +} +static inline short4 operator>>(short4 p, short4 q) +{ + return short4(p.x >> q.x, p.y >> q.y, p.z >> q.z, p.w >> q.w); +} +static inline short2 operator>>(short2 p, short q) +{ + return short2(p.x >> q, p.y >> q); +} +static inline short3 operator>>(short3 p, short q) +{ + return short3(p.x >> q, p.y >> q, p.z >> q); +} +static inline short4 operator>>(short4 p, short q) +{ + return short4(p.x >> q, p.y >> q, p.z >> q, p.w >> q); +} +static inline short2 operator>>(short p, short2 q) +{ + return short2(p >> q.x, p >> q.y); +} +static inline short3 operator>>(short p, short3 q) +{ + return short3(p >> q.x, p >> q.y, p >> q.z); +} +static inline short4 operator>>(short p, short4 q) +{ + return short4(p >> q.x, p >> q.y, p >> q.z, p >> q.w); +} +static inline ushort2 operator>>(ushort2 p, ushort2 q) +{ + return ushort2(p.x >> q.x, p.y >> q.y); +} +static inline ushort3 operator>>(ushort3 p, ushort3 q) +{ + return ushort3(p.x >> q.x, p.y >> q.y, p.z >> q.z); +} +static inline ushort4 operator>>(ushort4 p, ushort4 q) +{ + return ushort4(p.x >> q.x, p.y >> q.y, p.z >> q.z, p.w >> q.w); +} +static inline ushort2 operator>>(ushort2 p, ushort q) +{ + return ushort2(p.x >> q, p.y >> q); +} +static inline ushort3 operator>>(ushort3 p, ushort q) +{ + return ushort3(p.x >> q, p.y >> q, p.z >> q); +} +static inline ushort4 operator>>(ushort4 p, ushort q) +{ + return ushort4(p.x >> q, p.y >> q, p.z >> q, p.w >> q); +} +static inline ushort2 operator>>(ushort p, ushort2 q) +{ + return ushort2(p >> q.x, p >> q.y); +} +static inline ushort3 operator>>(ushort p, ushort3 q) +{ + return ushort3(p >> q.x, p >> q.y, p >> q.z); +} +static inline ushort4 operator>>(ushort p, ushort4 q) +{ + return ushort4(p >> q.x, p >> q.y, p >> q.z, p >> q.w); +} +static inline long2 operator>>(long2 p, long2 q) +{ + return long2(p.x >> q.x, p.y >> q.y); +} +static inline long3 operator>>(long3 p, long3 q) +{ + return long3(p.x >> q.x, p.y >> q.y, p.z >> q.z); +} +static inline long4 operator>>(long4 p, long4 q) +{ + return long4(p.x >> q.x, p.y >> q.y, p.z >> q.z, p.w >> q.w); +} +static inline long2 operator>>(long2 p, long q) +{ + return long2(p.x >> q, p.y >> q); +} +static inline long3 operator>>(long3 p, long q) +{ + return long3(p.x >> q, p.y >> q, p.z >> q); +} +static inline long4 operator>>(long4 p, long q) +{ + return long4(p.x >> q, p.y >> q, p.z >> q, p.w >> q); +} +static inline long2 operator>>(long p, long2 q) +{ + return long2(p >> q.x, p >> q.y); +} +static inline long3 operator>>(long p, long3 q) +{ + return long3(p >> q.x, p >> q.y, p >> q.z); +} +static inline long4 operator>>(long p, long4 q) +{ + return long4(p >> q.x, p >> q.y, p >> q.z, p >> q.w); +} +static inline ulong2 operator>>(ulong2 p, ulong2 q) +{ + return ulong2(p.x >> q.x, p.y >> q.y); +} +static inline ulong3 operator>>(ulong3 p, ulong3 q) +{ + return ulong3(p.x >> q.x, p.y >> q.y, p.z >> q.z); +} +static inline ulong4 operator>>(ulong4 p, ulong4 q) +{ + return ulong4(p.x >> q.x, p.y >> q.y, p.z >> q.z, p.w >> q.w); +} +static inline ulong2 operator>>(ulong2 p, ulong q) +{ + return ulong2(p.x >> q, p.y >> q); +} +static inline ulong3 operator>>(ulong3 p, ulong q) +{ + return ulong3(p.x >> q, p.y >> q, p.z >> q); +} +static inline ulong4 operator>>(ulong4 p, ulong q) +{ + return ulong4(p.x >> q, p.y >> q, p.z >> q, p.w >> q); +} +static inline ulong2 operator>>(ulong p, ulong2 q) +{ + return ulong2(p >> q.x, p >> q.y); +} +static inline ulong3 operator>>(ulong p, ulong3 q) +{ + return ulong3(p >> q.x, p >> q.y, p >> q.z); +} +static inline ulong4 operator>>(ulong p, ulong4 q) +{ + return ulong4(p >> q.x, p >> q.y, p >> q.z, p >> q.w); +} +static inline int2 operator==(float2 p, float2 q) +{ + return int2(p.x == q.x, p.y == q.y); +} +static inline int3 operator==(float3 p, float3 q) +{ + return int3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline int4 operator==(float4 p, float4 q) +{ + return int4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline int2 operator==(float2 p, float q) +{ + return int2(p.x == q, p.y == q); +} +static inline int3 operator==(float3 p, float q) +{ + return int3(p.x == q, p.y == q, p.z == q); +} +static inline int4 operator==(float4 p, float q) +{ + return int4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline int2 operator==(float p, float2 q) +{ + return int2(p == q.x, p == q.y); +} +static inline int3 operator==(float p, float3 q) +{ + return int3(p == q.x, p == q.y, p == q.z); +} +static inline int4 operator==(float p, float4 q) +{ + return int4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline long2 operator==(double2 p, double2 q) +{ + return long2(p.x == q.x, p.y == q.y); +} +static inline long3 operator==(double3 p, double3 q) +{ + return long3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline long4 operator==(double4 p, double4 q) +{ + return long4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline long2 operator==(double2 p, double q) +{ + return long2(p.x == q, p.y == q); +} +static inline long3 operator==(double3 p, double q) +{ + return long3(p.x == q, p.y == q, p.z == q); +} +static inline long4 operator==(double4 p, double q) +{ + return long4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline long2 operator==(double p, double2 q) +{ + return long2(p == q.x, p == q.y); +} +static inline long3 operator==(double p, double3 q) +{ + return long3(p == q.x, p == q.y, p == q.z); +} +static inline long4 operator==(double p, double4 q) +{ + return long4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline int2 operator==(int2 p, int2 q) +{ + return int2(p.x == q.x, p.y == q.y); +} +static inline int3 operator==(int3 p, int3 q) +{ + return int3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline int4 operator==(int4 p, int4 q) +{ + return int4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline int2 operator==(int2 p, int q) +{ + return int2(p.x == q, p.y == q); +} +static inline int3 operator==(int3 p, int q) +{ + return int3(p.x == q, p.y == q, p.z == q); +} +static inline int4 operator==(int4 p, int q) +{ + return int4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline int2 operator==(int p, int2 q) +{ + return int2(p == q.x, p == q.y); +} +static inline int3 operator==(int p, int3 q) +{ + return int3(p == q.x, p == q.y, p == q.z); +} +static inline int4 operator==(int p, int4 q) +{ + return int4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline int2 operator==(uint2 p, uint2 q) +{ + return int2(p.x == q.x, p.y == q.y); +} +static inline int3 operator==(uint3 p, uint3 q) +{ + return int3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline int4 operator==(uint4 p, uint4 q) +{ + return int4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline int2 operator==(uint2 p, uint q) +{ + return int2(p.x == q, p.y == q); +} +static inline int3 operator==(uint3 p, uint q) +{ + return int3(p.x == q, p.y == q, p.z == q); +} +static inline int4 operator==(uint4 p, uint q) +{ + return int4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline int2 operator==(uint p, uint2 q) +{ + return int2(p == q.x, p == q.y); +} +static inline int3 operator==(uint p, uint3 q) +{ + return int3(p == q.x, p == q.y, p == q.z); +} +static inline int4 operator==(uint p, uint4 q) +{ + return int4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline short2 operator==(short2 p, short2 q) +{ + return short2(p.x == q.x, p.y == q.y); +} +static inline short3 operator==(short3 p, short3 q) +{ + return short3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline short4 operator==(short4 p, short4 q) +{ + return short4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline short2 operator==(short2 p, short q) +{ + return short2(p.x == q, p.y == q); +} +static inline short3 operator==(short3 p, short q) +{ + return short3(p.x == q, p.y == q, p.z == q); +} +static inline short4 operator==(short4 p, short q) +{ + return short4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline short2 operator==(short p, short2 q) +{ + return short2(p == q.x, p == q.y); +} +static inline short3 operator==(short p, short3 q) +{ + return short3(p == q.x, p == q.y, p == q.z); +} +static inline short4 operator==(short p, short4 q) +{ + return short4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline short2 operator==(ushort2 p, ushort2 q) +{ + return short2(p.x == q.x, p.y == q.y); +} +static inline short3 operator==(ushort3 p, ushort3 q) +{ + return short3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline short4 operator==(ushort4 p, ushort4 q) +{ + return short4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline short2 operator==(ushort2 p, ushort q) +{ + return short2(p.x == q, p.y == q); +} +static inline short3 operator==(ushort3 p, ushort q) +{ + return short3(p.x == q, p.y == q, p.z == q); +} +static inline short4 operator==(ushort4 p, ushort q) +{ + return short4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline short2 operator==(ushort p, ushort2 q) +{ + return short2(p == q.x, p == q.y); +} +static inline short3 operator==(ushort p, ushort3 q) +{ + return short3(p == q.x, p == q.y, p == q.z); +} +static inline short4 operator==(ushort p, ushort4 q) +{ + return short4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline long2 operator==(long2 p, long2 q) +{ + return long2(p.x == q.x, p.y == q.y); +} +static inline long3 operator==(long3 p, long3 q) +{ + return long3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline long4 operator==(long4 p, long4 q) +{ + return long4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline long2 operator==(long2 p, long q) +{ + return long2(p.x == q, p.y == q); +} +static inline long3 operator==(long3 p, long q) +{ + return long3(p.x == q, p.y == q, p.z == q); +} +static inline long4 operator==(long4 p, long q) +{ + return long4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline long2 operator==(long p, long2 q) +{ + return long2(p == q.x, p == q.y); +} +static inline long3 operator==(long p, long3 q) +{ + return long3(p == q.x, p == q.y, p == q.z); +} +static inline long4 operator==(long p, long4 q) +{ + return long4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline long2 operator==(ulong2 p, ulong2 q) +{ + return long2(p.x == q.x, p.y == q.y); +} +static inline long3 operator==(ulong3 p, ulong3 q) +{ + return long3(p.x == q.x, p.y == q.y, p.z == q.z); +} +static inline long4 operator==(ulong4 p, ulong4 q) +{ + return long4(p.x == q.x, p.y == q.y, p.z == q.z, p.w == q.w); +} +static inline long2 operator==(ulong2 p, ulong q) +{ + return long2(p.x == q, p.y == q); +} +static inline long3 operator==(ulong3 p, ulong q) +{ + return long3(p.x == q, p.y == q, p.z == q); +} +static inline long4 operator==(ulong4 p, ulong q) +{ + return long4(p.x == q, p.y == q, p.z == q, p.w == q); +} +static inline long2 operator==(ulong p, ulong2 q) +{ + return long2(p == q.x, p == q.y); +} +static inline long3 operator==(ulong p, ulong3 q) +{ + return long3(p == q.x, p == q.y, p == q.z); +} +static inline long4 operator==(ulong p, ulong4 q) +{ + return long4(p == q.x, p == q.y, p == q.z, p == q.w); +} +static inline int2 operator!=(float2 p, float2 q) +{ + return int2(p.x != q.x, p.y != q.y); +} +static inline int3 operator!=(float3 p, float3 q) +{ + return int3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline int4 operator!=(float4 p, float4 q) +{ + return int4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline int2 operator!=(float2 p, float q) +{ + return int2(p.x != q, p.y != q); +} +static inline int3 operator!=(float3 p, float q) +{ + return int3(p.x != q, p.y != q, p.z != q); +} +static inline int4 operator!=(float4 p, float q) +{ + return int4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline int2 operator!=(float p, float2 q) +{ + return int2(p != q.x, p != q.y); +} +static inline int3 operator!=(float p, float3 q) +{ + return int3(p != q.x, p != q.y, p != q.z); +} +static inline int4 operator!=(float p, float4 q) +{ + return int4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline long2 operator!=(double2 p, double2 q) +{ + return long2(p.x != q.x, p.y != q.y); +} +static inline long3 operator!=(double3 p, double3 q) +{ + return long3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline long4 operator!=(double4 p, double4 q) +{ + return long4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline long2 operator!=(double2 p, double q) +{ + return long2(p.x != q, p.y != q); +} +static inline long3 operator!=(double3 p, double q) +{ + return long3(p.x != q, p.y != q, p.z != q); +} +static inline long4 operator!=(double4 p, double q) +{ + return long4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline long2 operator!=(double p, double2 q) +{ + return long2(p != q.x, p != q.y); +} +static inline long3 operator!=(double p, double3 q) +{ + return long3(p != q.x, p != q.y, p != q.z); +} +static inline long4 operator!=(double p, double4 q) +{ + return long4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline int2 operator!=(int2 p, int2 q) +{ + return int2(p.x != q.x, p.y != q.y); +} +static inline int3 operator!=(int3 p, int3 q) +{ + return int3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline int4 operator!=(int4 p, int4 q) +{ + return int4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline int2 operator!=(int2 p, int q) +{ + return int2(p.x != q, p.y != q); +} +static inline int3 operator!=(int3 p, int q) +{ + return int3(p.x != q, p.y != q, p.z != q); +} +static inline int4 operator!=(int4 p, int q) +{ + return int4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline int2 operator!=(int p, int2 q) +{ + return int2(p != q.x, p != q.y); +} +static inline int3 operator!=(int p, int3 q) +{ + return int3(p != q.x, p != q.y, p != q.z); +} +static inline int4 operator!=(int p, int4 q) +{ + return int4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline int2 operator!=(uint2 p, uint2 q) +{ + return int2(p.x != q.x, p.y != q.y); +} +static inline int3 operator!=(uint3 p, uint3 q) +{ + return int3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline int4 operator!=(uint4 p, uint4 q) +{ + return int4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline int2 operator!=(uint2 p, uint q) +{ + return int2(p.x != q, p.y != q); +} +static inline int3 operator!=(uint3 p, uint q) +{ + return int3(p.x != q, p.y != q, p.z != q); +} +static inline int4 operator!=(uint4 p, uint q) +{ + return int4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline int2 operator!=(uint p, uint2 q) +{ + return int2(p != q.x, p != q.y); +} +static inline int3 operator!=(uint p, uint3 q) +{ + return int3(p != q.x, p != q.y, p != q.z); +} +static inline int4 operator!=(uint p, uint4 q) +{ + return int4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline short2 operator!=(short2 p, short2 q) +{ + return short2(p.x != q.x, p.y != q.y); +} +static inline short3 operator!=(short3 p, short3 q) +{ + return short3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline short4 operator!=(short4 p, short4 q) +{ + return short4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline short2 operator!=(short2 p, short q) +{ + return short2(p.x != q, p.y != q); +} +static inline short3 operator!=(short3 p, short q) +{ + return short3(p.x != q, p.y != q, p.z != q); +} +static inline short4 operator!=(short4 p, short q) +{ + return short4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline short2 operator!=(short p, short2 q) +{ + return short2(p != q.x, p != q.y); +} +static inline short3 operator!=(short p, short3 q) +{ + return short3(p != q.x, p != q.y, p != q.z); +} +static inline short4 operator!=(short p, short4 q) +{ + return short4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline short2 operator!=(ushort2 p, ushort2 q) +{ + return short2(p.x != q.x, p.y != q.y); +} +static inline short3 operator!=(ushort3 p, ushort3 q) +{ + return short3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline short4 operator!=(ushort4 p, ushort4 q) +{ + return short4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline short2 operator!=(ushort2 p, ushort q) +{ + return short2(p.x != q, p.y != q); +} +static inline short3 operator!=(ushort3 p, ushort q) +{ + return short3(p.x != q, p.y != q, p.z != q); +} +static inline short4 operator!=(ushort4 p, ushort q) +{ + return short4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline short2 operator!=(ushort p, ushort2 q) +{ + return short2(p != q.x, p != q.y); +} +static inline short3 operator!=(ushort p, ushort3 q) +{ + return short3(p != q.x, p != q.y, p != q.z); +} +static inline short4 operator!=(ushort p, ushort4 q) +{ + return short4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline long2 operator!=(long2 p, long2 q) +{ + return long2(p.x != q.x, p.y != q.y); +} +static inline long3 operator!=(long3 p, long3 q) +{ + return long3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline long4 operator!=(long4 p, long4 q) +{ + return long4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline long2 operator!=(long2 p, long q) +{ + return long2(p.x != q, p.y != q); +} +static inline long3 operator!=(long3 p, long q) +{ + return long3(p.x != q, p.y != q, p.z != q); +} +static inline long4 operator!=(long4 p, long q) +{ + return long4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline long2 operator!=(long p, long2 q) +{ + return long2(p != q.x, p != q.y); +} +static inline long3 operator!=(long p, long3 q) +{ + return long3(p != q.x, p != q.y, p != q.z); +} +static inline long4 operator!=(long p, long4 q) +{ + return long4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline long2 operator!=(ulong2 p, ulong2 q) +{ + return long2(p.x != q.x, p.y != q.y); +} +static inline long3 operator!=(ulong3 p, ulong3 q) +{ + return long3(p.x != q.x, p.y != q.y, p.z != q.z); +} +static inline long4 operator!=(ulong4 p, ulong4 q) +{ + return long4(p.x != q.x, p.y != q.y, p.z != q.z, p.w != q.w); +} +static inline long2 operator!=(ulong2 p, ulong q) +{ + return long2(p.x != q, p.y != q); +} +static inline long3 operator!=(ulong3 p, ulong q) +{ + return long3(p.x != q, p.y != q, p.z != q); +} +static inline long4 operator!=(ulong4 p, ulong q) +{ + return long4(p.x != q, p.y != q, p.z != q, p.w != q); +} +static inline long2 operator!=(ulong p, ulong2 q) +{ + return long2(p != q.x, p != q.y); +} +static inline long3 operator!=(ulong p, ulong3 q) +{ + return long3(p != q.x, p != q.y, p != q.z); +} +static inline long4 operator!=(ulong p, ulong4 q) +{ + return long4(p != q.x, p != q.y, p != q.z, p != q.w); +} +static inline int2 operator>(float2 p, float2 q) +{ + return int2(p.x > q.x, p.y > q.y); +} +static inline int3 operator>(float3 p, float3 q) +{ + return int3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline int4 operator>(float4 p, float4 q) +{ + return int4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline int2 operator>(float2 p, float q) +{ + return int2(p.x > q, p.y > q); +} +static inline int3 operator>(float3 p, float q) +{ + return int3(p.x > q, p.y > q, p.z > q); +} +static inline int4 operator>(float4 p, float q) +{ + return int4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline int2 operator>(float p, float2 q) +{ + return int2(p > q.x, p > q.y); +} +static inline int3 operator>(float p, float3 q) +{ + return int3(p > q.x, p > q.y, p > q.z); +} +static inline int4 operator>(float p, float4 q) +{ + return int4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline long2 operator>(double2 p, double2 q) +{ + return long2(p.x > q.x, p.y > q.y); +} +static inline long3 operator>(double3 p, double3 q) +{ + return long3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline long4 operator>(double4 p, double4 q) +{ + return long4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline long2 operator>(double2 p, double q) +{ + return long2(p.x > q, p.y > q); +} +static inline long3 operator>(double3 p, double q) +{ + return long3(p.x > q, p.y > q, p.z > q); +} +static inline long4 operator>(double4 p, double q) +{ + return long4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline long2 operator>(double p, double2 q) +{ + return long2(p > q.x, p > q.y); +} +static inline long3 operator>(double p, double3 q) +{ + return long3(p > q.x, p > q.y, p > q.z); +} +static inline long4 operator>(double p, double4 q) +{ + return long4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline int2 operator>(int2 p, int2 q) +{ + return int2(p.x > q.x, p.y > q.y); +} +static inline int3 operator>(int3 p, int3 q) +{ + return int3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline int4 operator>(int4 p, int4 q) +{ + return int4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline int2 operator>(int2 p, int q) +{ + return int2(p.x > q, p.y > q); +} +static inline int3 operator>(int3 p, int q) +{ + return int3(p.x > q, p.y > q, p.z > q); +} +static inline int4 operator>(int4 p, int q) +{ + return int4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline int2 operator>(int p, int2 q) +{ + return int2(p > q.x, p > q.y); +} +static inline int3 operator>(int p, int3 q) +{ + return int3(p > q.x, p > q.y, p > q.z); +} +static inline int4 operator>(int p, int4 q) +{ + return int4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline int2 operator>(uint2 p, uint2 q) +{ + return int2(p.x > q.x, p.y > q.y); +} +static inline int3 operator>(uint3 p, uint3 q) +{ + return int3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline int4 operator>(uint4 p, uint4 q) +{ + return int4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline int2 operator>(uint2 p, uint q) +{ + return int2(p.x > q, p.y > q); +} +static inline int3 operator>(uint3 p, uint q) +{ + return int3(p.x > q, p.y > q, p.z > q); +} +static inline int4 operator>(uint4 p, uint q) +{ + return int4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline int2 operator>(uint p, uint2 q) +{ + return int2(p > q.x, p > q.y); +} +static inline int3 operator>(uint p, uint3 q) +{ + return int3(p > q.x, p > q.y, p > q.z); +} +static inline int4 operator>(uint p, uint4 q) +{ + return int4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline short2 operator>(short2 p, short2 q) +{ + return short2(p.x > q.x, p.y > q.y); +} +static inline short3 operator>(short3 p, short3 q) +{ + return short3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline short4 operator>(short4 p, short4 q) +{ + return short4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline short2 operator>(short2 p, short q) +{ + return short2(p.x > q, p.y > q); +} +static inline short3 operator>(short3 p, short q) +{ + return short3(p.x > q, p.y > q, p.z > q); +} +static inline short4 operator>(short4 p, short q) +{ + return short4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline short2 operator>(short p, short2 q) +{ + return short2(p > q.x, p > q.y); +} +static inline short3 operator>(short p, short3 q) +{ + return short3(p > q.x, p > q.y, p > q.z); +} +static inline short4 operator>(short p, short4 q) +{ + return short4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline short2 operator>(ushort2 p, ushort2 q) +{ + return short2(p.x > q.x, p.y > q.y); +} +static inline short3 operator>(ushort3 p, ushort3 q) +{ + return short3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline short4 operator>(ushort4 p, ushort4 q) +{ + return short4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline short2 operator>(ushort2 p, ushort q) +{ + return short2(p.x > q, p.y > q); +} +static inline short3 operator>(ushort3 p, ushort q) +{ + return short3(p.x > q, p.y > q, p.z > q); +} +static inline short4 operator>(ushort4 p, ushort q) +{ + return short4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline short2 operator>(ushort p, ushort2 q) +{ + return short2(p > q.x, p > q.y); +} +static inline short3 operator>(ushort p, ushort3 q) +{ + return short3(p > q.x, p > q.y, p > q.z); +} +static inline short4 operator>(ushort p, ushort4 q) +{ + return short4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline long2 operator>(long2 p, long2 q) +{ + return long2(p.x > q.x, p.y > q.y); +} +static inline long3 operator>(long3 p, long3 q) +{ + return long3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline long4 operator>(long4 p, long4 q) +{ + return long4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline long2 operator>(long2 p, long q) +{ + return long2(p.x > q, p.y > q); +} +static inline long3 operator>(long3 p, long q) +{ + return long3(p.x > q, p.y > q, p.z > q); +} +static inline long4 operator>(long4 p, long q) +{ + return long4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline long2 operator>(long p, long2 q) +{ + return long2(p > q.x, p > q.y); +} +static inline long3 operator>(long p, long3 q) +{ + return long3(p > q.x, p > q.y, p > q.z); +} +static inline long4 operator>(long p, long4 q) +{ + return long4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline long2 operator>(ulong2 p, ulong2 q) +{ + return long2(p.x > q.x, p.y > q.y); +} +static inline long3 operator>(ulong3 p, ulong3 q) +{ + return long3(p.x > q.x, p.y > q.y, p.z > q.z); +} +static inline long4 operator>(ulong4 p, ulong4 q) +{ + return long4(p.x > q.x, p.y > q.y, p.z > q.z, p.w > q.w); +} +static inline long2 operator>(ulong2 p, ulong q) +{ + return long2(p.x > q, p.y > q); +} +static inline long3 operator>(ulong3 p, ulong q) +{ + return long3(p.x > q, p.y > q, p.z > q); +} +static inline long4 operator>(ulong4 p, ulong q) +{ + return long4(p.x > q, p.y > q, p.z > q, p.w > q); +} +static inline long2 operator>(ulong p, ulong2 q) +{ + return long2(p > q.x, p > q.y); +} +static inline long3 operator>(ulong p, ulong3 q) +{ + return long3(p > q.x, p > q.y, p > q.z); +} +static inline long4 operator>(ulong p, ulong4 q) +{ + return long4(p > q.x, p > q.y, p > q.z, p > q.w); +} +static inline int2 operator<(float2 p, float2 q) +{ + return int2(p.x < q.x, p.y < q.y); +} +static inline int3 operator<(float3 p, float3 q) +{ + return int3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline int4 operator<(float4 p, float4 q) +{ + return int4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline int2 operator<(float2 p, float q) +{ + return int2(p.x < q, p.y < q); +} +static inline int3 operator<(float3 p, float q) +{ + return int3(p.x < q, p.y < q, p.z < q); +} +static inline int4 operator<(float4 p, float q) +{ + return int4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline int2 operator<(float p, float2 q) +{ + return int2(p < q.x, p < q.y); +} +static inline int3 operator<(float p, float3 q) +{ + return int3(p < q.x, p < q.y, p < q.z); +} +static inline int4 operator<(float p, float4 q) +{ + return int4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline long2 operator<(double2 p, double2 q) +{ + return long2(p.x < q.x, p.y < q.y); +} +static inline long3 operator<(double3 p, double3 q) +{ + return long3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline long4 operator<(double4 p, double4 q) +{ + return long4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline long2 operator<(double2 p, double q) +{ + return long2(p.x < q, p.y < q); +} +static inline long3 operator<(double3 p, double q) +{ + return long3(p.x < q, p.y < q, p.z < q); +} +static inline long4 operator<(double4 p, double q) +{ + return long4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline long2 operator<(double p, double2 q) +{ + return long2(p < q.x, p < q.y); +} +static inline long3 operator<(double p, double3 q) +{ + return long3(p < q.x, p < q.y, p < q.z); +} +static inline long4 operator<(double p, double4 q) +{ + return long4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline int2 operator<(int2 p, int2 q) +{ + return int2(p.x < q.x, p.y < q.y); +} +static inline int3 operator<(int3 p, int3 q) +{ + return int3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline int4 operator<(int4 p, int4 q) +{ + return int4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline int2 operator<(int2 p, int q) +{ + return int2(p.x < q, p.y < q); +} +static inline int3 operator<(int3 p, int q) +{ + return int3(p.x < q, p.y < q, p.z < q); +} +static inline int4 operator<(int4 p, int q) +{ + return int4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline int2 operator<(int p, int2 q) +{ + return int2(p < q.x, p < q.y); +} +static inline int3 operator<(int p, int3 q) +{ + return int3(p < q.x, p < q.y, p < q.z); +} +static inline int4 operator<(int p, int4 q) +{ + return int4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline int2 operator<(uint2 p, uint2 q) +{ + return int2(p.x < q.x, p.y < q.y); +} +static inline int3 operator<(uint3 p, uint3 q) +{ + return int3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline int4 operator<(uint4 p, uint4 q) +{ + return int4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline int2 operator<(uint2 p, uint q) +{ + return int2(p.x < q, p.y < q); +} +static inline int3 operator<(uint3 p, uint q) +{ + return int3(p.x < q, p.y < q, p.z < q); +} +static inline int4 operator<(uint4 p, uint q) +{ + return int4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline int2 operator<(uint p, uint2 q) +{ + return int2(p < q.x, p < q.y); +} +static inline int3 operator<(uint p, uint3 q) +{ + return int3(p < q.x, p < q.y, p < q.z); +} +static inline int4 operator<(uint p, uint4 q) +{ + return int4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline short2 operator<(short2 p, short2 q) +{ + return short2(p.x < q.x, p.y < q.y); +} +static inline short3 operator<(short3 p, short3 q) +{ + return short3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline short4 operator<(short4 p, short4 q) +{ + return short4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline short2 operator<(short2 p, short q) +{ + return short2(p.x < q, p.y < q); +} +static inline short3 operator<(short3 p, short q) +{ + return short3(p.x < q, p.y < q, p.z < q); +} +static inline short4 operator<(short4 p, short q) +{ + return short4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline short2 operator<(short p, short2 q) +{ + return short2(p < q.x, p < q.y); +} +static inline short3 operator<(short p, short3 q) +{ + return short3(p < q.x, p < q.y, p < q.z); +} +static inline short4 operator<(short p, short4 q) +{ + return short4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline short2 operator<(ushort2 p, ushort2 q) +{ + return short2(p.x < q.x, p.y < q.y); +} +static inline short3 operator<(ushort3 p, ushort3 q) +{ + return short3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline short4 operator<(ushort4 p, ushort4 q) +{ + return short4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline short2 operator<(ushort2 p, ushort q) +{ + return short2(p.x < q, p.y < q); +} +static inline short3 operator<(ushort3 p, ushort q) +{ + return short3(p.x < q, p.y < q, p.z < q); +} +static inline short4 operator<(ushort4 p, ushort q) +{ + return short4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline short2 operator<(ushort p, ushort2 q) +{ + return short2(p < q.x, p < q.y); +} +static inline short3 operator<(ushort p, ushort3 q) +{ + return short3(p < q.x, p < q.y, p < q.z); +} +static inline short4 operator<(ushort p, ushort4 q) +{ + return short4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline long2 operator<(long2 p, long2 q) +{ + return long2(p.x < q.x, p.y < q.y); +} +static inline long3 operator<(long3 p, long3 q) +{ + return long3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline long4 operator<(long4 p, long4 q) +{ + return long4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline long2 operator<(long2 p, long q) +{ + return long2(p.x < q, p.y < q); +} +static inline long3 operator<(long3 p, long q) +{ + return long3(p.x < q, p.y < q, p.z < q); +} +static inline long4 operator<(long4 p, long q) +{ + return long4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline long2 operator<(long p, long2 q) +{ + return long2(p < q.x, p < q.y); +} +static inline long3 operator<(long p, long3 q) +{ + return long3(p < q.x, p < q.y, p < q.z); +} +static inline long4 operator<(long p, long4 q) +{ + return long4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline long2 operator<(ulong2 p, ulong2 q) +{ + return long2(p.x < q.x, p.y < q.y); +} +static inline long3 operator<(ulong3 p, ulong3 q) +{ + return long3(p.x < q.x, p.y < q.y, p.z < q.z); +} +static inline long4 operator<(ulong4 p, ulong4 q) +{ + return long4(p.x < q.x, p.y < q.y, p.z < q.z, p.w < q.w); +} +static inline long2 operator<(ulong2 p, ulong q) +{ + return long2(p.x < q, p.y < q); +} +static inline long3 operator<(ulong3 p, ulong q) +{ + return long3(p.x < q, p.y < q, p.z < q); +} +static inline long4 operator<(ulong4 p, ulong q) +{ + return long4(p.x < q, p.y < q, p.z < q, p.w < q); +} +static inline long2 operator<(ulong p, ulong2 q) +{ + return long2(p < q.x, p < q.y); +} +static inline long3 operator<(ulong p, ulong3 q) +{ + return long3(p < q.x, p < q.y, p < q.z); +} +static inline long4 operator<(ulong p, ulong4 q) +{ + return long4(p < q.x, p < q.y, p < q.z, p < q.w); +} +static inline int2 operator>=(float2 p, float2 q) +{ + return int2(p.x >= q.x, p.y >= q.y); +} +static inline int3 operator>=(float3 p, float3 q) +{ + return int3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline int4 operator>=(float4 p, float4 q) +{ + return int4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline int2 operator>=(float2 p, float q) +{ + return int2(p.x >= q, p.y >= q); +} +static inline int3 operator>=(float3 p, float q) +{ + return int3(p.x >= q, p.y >= q, p.z >= q); +} +static inline int4 operator>=(float4 p, float q) +{ + return int4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline int2 operator>=(float p, float2 q) +{ + return int2(p >= q.x, p >= q.y); +} +static inline int3 operator>=(float p, float3 q) +{ + return int3(p >= q.x, p >= q.y, p >= q.z); +} +static inline int4 operator>=(float p, float4 q) +{ + return int4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline long2 operator>=(double2 p, double2 q) +{ + return long2(p.x >= q.x, p.y >= q.y); +} +static inline long3 operator>=(double3 p, double3 q) +{ + return long3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline long4 operator>=(double4 p, double4 q) +{ + return long4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline long2 operator>=(double2 p, double q) +{ + return long2(p.x >= q, p.y >= q); +} +static inline long3 operator>=(double3 p, double q) +{ + return long3(p.x >= q, p.y >= q, p.z >= q); +} +static inline long4 operator>=(double4 p, double q) +{ + return long4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline long2 operator>=(double p, double2 q) +{ + return long2(p >= q.x, p >= q.y); +} +static inline long3 operator>=(double p, double3 q) +{ + return long3(p >= q.x, p >= q.y, p >= q.z); +} +static inline long4 operator>=(double p, double4 q) +{ + return long4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline int2 operator>=(int2 p, int2 q) +{ + return int2(p.x >= q.x, p.y >= q.y); +} +static inline int3 operator>=(int3 p, int3 q) +{ + return int3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline int4 operator>=(int4 p, int4 q) +{ + return int4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline int2 operator>=(int2 p, int q) +{ + return int2(p.x >= q, p.y >= q); +} +static inline int3 operator>=(int3 p, int q) +{ + return int3(p.x >= q, p.y >= q, p.z >= q); +} +static inline int4 operator>=(int4 p, int q) +{ + return int4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline int2 operator>=(int p, int2 q) +{ + return int2(p >= q.x, p >= q.y); +} +static inline int3 operator>=(int p, int3 q) +{ + return int3(p >= q.x, p >= q.y, p >= q.z); +} +static inline int4 operator>=(int p, int4 q) +{ + return int4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline int2 operator>=(uint2 p, uint2 q) +{ + return int2(p.x >= q.x, p.y >= q.y); +} +static inline int3 operator>=(uint3 p, uint3 q) +{ + return int3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline int4 operator>=(uint4 p, uint4 q) +{ + return int4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline int2 operator>=(uint2 p, uint q) +{ + return int2(p.x >= q, p.y >= q); +} +static inline int3 operator>=(uint3 p, uint q) +{ + return int3(p.x >= q, p.y >= q, p.z >= q); +} +static inline int4 operator>=(uint4 p, uint q) +{ + return int4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline int2 operator>=(uint p, uint2 q) +{ + return int2(p >= q.x, p >= q.y); +} +static inline int3 operator>=(uint p, uint3 q) +{ + return int3(p >= q.x, p >= q.y, p >= q.z); +} +static inline int4 operator>=(uint p, uint4 q) +{ + return int4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline short2 operator>=(short2 p, short2 q) +{ + return short2(p.x >= q.x, p.y >= q.y); +} +static inline short3 operator>=(short3 p, short3 q) +{ + return short3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline short4 operator>=(short4 p, short4 q) +{ + return short4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline short2 operator>=(short2 p, short q) +{ + return short2(p.x >= q, p.y >= q); +} +static inline short3 operator>=(short3 p, short q) +{ + return short3(p.x >= q, p.y >= q, p.z >= q); +} +static inline short4 operator>=(short4 p, short q) +{ + return short4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline short2 operator>=(short p, short2 q) +{ + return short2(p >= q.x, p >= q.y); +} +static inline short3 operator>=(short p, short3 q) +{ + return short3(p >= q.x, p >= q.y, p >= q.z); +} +static inline short4 operator>=(short p, short4 q) +{ + return short4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline short2 operator>=(ushort2 p, ushort2 q) +{ + return short2(p.x >= q.x, p.y >= q.y); +} +static inline short3 operator>=(ushort3 p, ushort3 q) +{ + return short3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline short4 operator>=(ushort4 p, ushort4 q) +{ + return short4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline short2 operator>=(ushort2 p, ushort q) +{ + return short2(p.x >= q, p.y >= q); +} +static inline short3 operator>=(ushort3 p, ushort q) +{ + return short3(p.x >= q, p.y >= q, p.z >= q); +} +static inline short4 operator>=(ushort4 p, ushort q) +{ + return short4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline short2 operator>=(ushort p, ushort2 q) +{ + return short2(p >= q.x, p >= q.y); +} +static inline short3 operator>=(ushort p, ushort3 q) +{ + return short3(p >= q.x, p >= q.y, p >= q.z); +} +static inline short4 operator>=(ushort p, ushort4 q) +{ + return short4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline long2 operator>=(long2 p, long2 q) +{ + return long2(p.x >= q.x, p.y >= q.y); +} +static inline long3 operator>=(long3 p, long3 q) +{ + return long3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline long4 operator>=(long4 p, long4 q) +{ + return long4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline long2 operator>=(long2 p, long q) +{ + return long2(p.x >= q, p.y >= q); +} +static inline long3 operator>=(long3 p, long q) +{ + return long3(p.x >= q, p.y >= q, p.z >= q); +} +static inline long4 operator>=(long4 p, long q) +{ + return long4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline long2 operator>=(long p, long2 q) +{ + return long2(p >= q.x, p >= q.y); +} +static inline long3 operator>=(long p, long3 q) +{ + return long3(p >= q.x, p >= q.y, p >= q.z); +} +static inline long4 operator>=(long p, long4 q) +{ + return long4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline long2 operator>=(ulong2 p, ulong2 q) +{ + return long2(p.x >= q.x, p.y >= q.y); +} +static inline long3 operator>=(ulong3 p, ulong3 q) +{ + return long3(p.x >= q.x, p.y >= q.y, p.z >= q.z); +} +static inline long4 operator>=(ulong4 p, ulong4 q) +{ + return long4(p.x >= q.x, p.y >= q.y, p.z >= q.z, p.w >= q.w); +} +static inline long2 operator>=(ulong2 p, ulong q) +{ + return long2(p.x >= q, p.y >= q); +} +static inline long3 operator>=(ulong3 p, ulong q) +{ + return long3(p.x >= q, p.y >= q, p.z >= q); +} +static inline long4 operator>=(ulong4 p, ulong q) +{ + return long4(p.x >= q, p.y >= q, p.z >= q, p.w >= q); +} +static inline long2 operator>=(ulong p, ulong2 q) +{ + return long2(p >= q.x, p >= q.y); +} +static inline long3 operator>=(ulong p, ulong3 q) +{ + return long3(p >= q.x, p >= q.y, p >= q.z); +} +static inline long4 operator>=(ulong p, ulong4 q) +{ + return long4(p >= q.x, p >= q.y, p >= q.z, p >= q.w); +} +static inline int2 operator<=(float2 p, float2 q) +{ + return int2(p.x <= q.x, p.y <= q.y); +} +static inline int3 operator<=(float3 p, float3 q) +{ + return int3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline int4 operator<=(float4 p, float4 q) +{ + return int4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline int2 operator<=(float2 p, float q) +{ + return int2(p.x <= q, p.y <= q); +} +static inline int3 operator<=(float3 p, float q) +{ + return int3(p.x <= q, p.y <= q, p.z <= q); +} +static inline int4 operator<=(float4 p, float q) +{ + return int4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline int2 operator<=(float p, float2 q) +{ + return int2(p <= q.x, p <= q.y); +} +static inline int3 operator<=(float p, float3 q) +{ + return int3(p <= q.x, p <= q.y, p <= q.z); +} +static inline int4 operator<=(float p, float4 q) +{ + return int4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline long2 operator<=(double2 p, double2 q) +{ + return long2(p.x <= q.x, p.y <= q.y); +} +static inline long3 operator<=(double3 p, double3 q) +{ + return long3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline long4 operator<=(double4 p, double4 q) +{ + return long4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline long2 operator<=(double2 p, double q) +{ + return long2(p.x <= q, p.y <= q); +} +static inline long3 operator<=(double3 p, double q) +{ + return long3(p.x <= q, p.y <= q, p.z <= q); +} +static inline long4 operator<=(double4 p, double q) +{ + return long4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline long2 operator<=(double p, double2 q) +{ + return long2(p <= q.x, p <= q.y); +} +static inline long3 operator<=(double p, double3 q) +{ + return long3(p <= q.x, p <= q.y, p <= q.z); +} +static inline long4 operator<=(double p, double4 q) +{ + return long4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline int2 operator<=(int2 p, int2 q) +{ + return int2(p.x <= q.x, p.y <= q.y); +} +static inline int3 operator<=(int3 p, int3 q) +{ + return int3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline int4 operator<=(int4 p, int4 q) +{ + return int4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline int2 operator<=(int2 p, int q) +{ + return int2(p.x <= q, p.y <= q); +} +static inline int3 operator<=(int3 p, int q) +{ + return int3(p.x <= q, p.y <= q, p.z <= q); +} +static inline int4 operator<=(int4 p, int q) +{ + return int4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline int2 operator<=(int p, int2 q) +{ + return int2(p <= q.x, p <= q.y); +} +static inline int3 operator<=(int p, int3 q) +{ + return int3(p <= q.x, p <= q.y, p <= q.z); +} +static inline int4 operator<=(int p, int4 q) +{ + return int4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline int2 operator<=(uint2 p, uint2 q) +{ + return int2(p.x <= q.x, p.y <= q.y); +} +static inline int3 operator<=(uint3 p, uint3 q) +{ + return int3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline int4 operator<=(uint4 p, uint4 q) +{ + return int4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline int2 operator<=(uint2 p, uint q) +{ + return int2(p.x <= q, p.y <= q); +} +static inline int3 operator<=(uint3 p, uint q) +{ + return int3(p.x <= q, p.y <= q, p.z <= q); +} +static inline int4 operator<=(uint4 p, uint q) +{ + return int4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline int2 operator<=(uint p, uint2 q) +{ + return int2(p <= q.x, p <= q.y); +} +static inline int3 operator<=(uint p, uint3 q) +{ + return int3(p <= q.x, p <= q.y, p <= q.z); +} +static inline int4 operator<=(uint p, uint4 q) +{ + return int4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline short2 operator<=(short2 p, short2 q) +{ + return short2(p.x <= q.x, p.y <= q.y); +} +static inline short3 operator<=(short3 p, short3 q) +{ + return short3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline short4 operator<=(short4 p, short4 q) +{ + return short4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline short2 operator<=(short2 p, short q) +{ + return short2(p.x <= q, p.y <= q); +} +static inline short3 operator<=(short3 p, short q) +{ + return short3(p.x <= q, p.y <= q, p.z <= q); +} +static inline short4 operator<=(short4 p, short q) +{ + return short4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline short2 operator<=(short p, short2 q) +{ + return short2(p <= q.x, p <= q.y); +} +static inline short3 operator<=(short p, short3 q) +{ + return short3(p <= q.x, p <= q.y, p <= q.z); +} +static inline short4 operator<=(short p, short4 q) +{ + return short4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline short2 operator<=(ushort2 p, ushort2 q) +{ + return short2(p.x <= q.x, p.y <= q.y); +} +static inline short3 operator<=(ushort3 p, ushort3 q) +{ + return short3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline short4 operator<=(ushort4 p, ushort4 q) +{ + return short4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline short2 operator<=(ushort2 p, ushort q) +{ + return short2(p.x <= q, p.y <= q); +} +static inline short3 operator<=(ushort3 p, ushort q) +{ + return short3(p.x <= q, p.y <= q, p.z <= q); +} +static inline short4 operator<=(ushort4 p, ushort q) +{ + return short4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline short2 operator<=(ushort p, ushort2 q) +{ + return short2(p <= q.x, p <= q.y); +} +static inline short3 operator<=(ushort p, ushort3 q) +{ + return short3(p <= q.x, p <= q.y, p <= q.z); +} +static inline short4 operator<=(ushort p, ushort4 q) +{ + return short4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline long2 operator<=(long2 p, long2 q) +{ + return long2(p.x <= q.x, p.y <= q.y); +} +static inline long3 operator<=(long3 p, long3 q) +{ + return long3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline long4 operator<=(long4 p, long4 q) +{ + return long4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline long2 operator<=(long2 p, long q) +{ + return long2(p.x <= q, p.y <= q); +} +static inline long3 operator<=(long3 p, long q) +{ + return long3(p.x <= q, p.y <= q, p.z <= q); +} +static inline long4 operator<=(long4 p, long q) +{ + return long4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline long2 operator<=(long p, long2 q) +{ + return long2(p <= q.x, p <= q.y); +} +static inline long3 operator<=(long p, long3 q) +{ + return long3(p <= q.x, p <= q.y, p <= q.z); +} +static inline long4 operator<=(long p, long4 q) +{ + return long4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline long2 operator<=(ulong2 p, ulong2 q) +{ + return long2(p.x <= q.x, p.y <= q.y); +} +static inline long3 operator<=(ulong3 p, ulong3 q) +{ + return long3(p.x <= q.x, p.y <= q.y, p.z <= q.z); +} +static inline long4 operator<=(ulong4 p, ulong4 q) +{ + return long4(p.x <= q.x, p.y <= q.y, p.z <= q.z, p.w <= q.w); +} +static inline long2 operator<=(ulong2 p, ulong q) +{ + return long2(p.x <= q, p.y <= q); +} +static inline long3 operator<=(ulong3 p, ulong q) +{ + return long3(p.x <= q, p.y <= q, p.z <= q); +} +static inline long4 operator<=(ulong4 p, ulong q) +{ + return long4(p.x <= q, p.y <= q, p.z <= q, p.w <= q); +} +static inline long2 operator<=(ulong p, ulong2 q) +{ + return long2(p <= q.x, p <= q.y); +} +static inline long3 operator<=(ulong p, ulong3 q) +{ + return long3(p <= q.x, p <= q.y, p <= q.z); +} +static inline long4 operator<=(ulong p, ulong4 q) +{ + return long4(p <= q.x, p <= q.y, p <= q.z, p <= q.w); +} +static inline int2 operator&&(float2 p, float2 q) +{ + return int2(p.x && q.x, p.y && q.y); +} +static inline int3 operator&&(float3 p, float3 q) +{ + return int3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline int4 operator&&(float4 p, float4 q) +{ + return int4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline int2 operator&&(float2 p, float q) +{ + return int2(p.x && q, p.y && q); +} +static inline int3 operator&&(float3 p, float q) +{ + return int3(p.x && q, p.y && q, p.z && q); +} +static inline int4 operator&&(float4 p, float q) +{ + return int4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline int2 operator&&(float p, float2 q) +{ + return int2(p && q.x, p && q.y); +} +static inline int3 operator&&(float p, float3 q) +{ + return int3(p && q.x, p && q.y, p && q.z); +} +static inline int4 operator&&(float p, float4 q) +{ + return int4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline long2 operator&&(double2 p, double2 q) +{ + return long2(p.x && q.x, p.y && q.y); +} +static inline long3 operator&&(double3 p, double3 q) +{ + return long3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline long4 operator&&(double4 p, double4 q) +{ + return long4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline long2 operator&&(double2 p, double q) +{ + return long2(p.x && q, p.y && q); +} +static inline long3 operator&&(double3 p, double q) +{ + return long3(p.x && q, p.y && q, p.z && q); +} +static inline long4 operator&&(double4 p, double q) +{ + return long4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline long2 operator&&(double p, double2 q) +{ + return long2(p && q.x, p && q.y); +} +static inline long3 operator&&(double p, double3 q) +{ + return long3(p && q.x, p && q.y, p && q.z); +} +static inline long4 operator&&(double p, double4 q) +{ + return long4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline int2 operator&&(int2 p, int2 q) +{ + return int2(p.x && q.x, p.y && q.y); +} +static inline int3 operator&&(int3 p, int3 q) +{ + return int3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline int4 operator&&(int4 p, int4 q) +{ + return int4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline int2 operator&&(int2 p, int q) +{ + return int2(p.x && q, p.y && q); +} +static inline int3 operator&&(int3 p, int q) +{ + return int3(p.x && q, p.y && q, p.z && q); +} +static inline int4 operator&&(int4 p, int q) +{ + return int4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline int2 operator&&(int p, int2 q) +{ + return int2(p && q.x, p && q.y); +} +static inline int3 operator&&(int p, int3 q) +{ + return int3(p && q.x, p && q.y, p && q.z); +} +static inline int4 operator&&(int p, int4 q) +{ + return int4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline int2 operator&&(uint2 p, uint2 q) +{ + return int2(p.x && q.x, p.y && q.y); +} +static inline int3 operator&&(uint3 p, uint3 q) +{ + return int3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline int4 operator&&(uint4 p, uint4 q) +{ + return int4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline int2 operator&&(uint2 p, uint q) +{ + return int2(p.x && q, p.y && q); +} +static inline int3 operator&&(uint3 p, uint q) +{ + return int3(p.x && q, p.y && q, p.z && q); +} +static inline int4 operator&&(uint4 p, uint q) +{ + return int4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline int2 operator&&(uint p, uint2 q) +{ + return int2(p && q.x, p && q.y); +} +static inline int3 operator&&(uint p, uint3 q) +{ + return int3(p && q.x, p && q.y, p && q.z); +} +static inline int4 operator&&(uint p, uint4 q) +{ + return int4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline short2 operator&&(short2 p, short2 q) +{ + return short2(p.x && q.x, p.y && q.y); +} +static inline short3 operator&&(short3 p, short3 q) +{ + return short3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline short4 operator&&(short4 p, short4 q) +{ + return short4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline short2 operator&&(short2 p, short q) +{ + return short2(p.x && q, p.y && q); +} +static inline short3 operator&&(short3 p, short q) +{ + return short3(p.x && q, p.y && q, p.z && q); +} +static inline short4 operator&&(short4 p, short q) +{ + return short4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline short2 operator&&(short p, short2 q) +{ + return short2(p && q.x, p && q.y); +} +static inline short3 operator&&(short p, short3 q) +{ + return short3(p && q.x, p && q.y, p && q.z); +} +static inline short4 operator&&(short p, short4 q) +{ + return short4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline short2 operator&&(ushort2 p, ushort2 q) +{ + return short2(p.x && q.x, p.y && q.y); +} +static inline short3 operator&&(ushort3 p, ushort3 q) +{ + return short3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline short4 operator&&(ushort4 p, ushort4 q) +{ + return short4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline short2 operator&&(ushort2 p, ushort q) +{ + return short2(p.x && q, p.y && q); +} +static inline short3 operator&&(ushort3 p, ushort q) +{ + return short3(p.x && q, p.y && q, p.z && q); +} +static inline short4 operator&&(ushort4 p, ushort q) +{ + return short4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline short2 operator&&(ushort p, ushort2 q) +{ + return short2(p && q.x, p && q.y); +} +static inline short3 operator&&(ushort p, ushort3 q) +{ + return short3(p && q.x, p && q.y, p && q.z); +} +static inline short4 operator&&(ushort p, ushort4 q) +{ + return short4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline long2 operator&&(long2 p, long2 q) +{ + return long2(p.x && q.x, p.y && q.y); +} +static inline long3 operator&&(long3 p, long3 q) +{ + return long3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline long4 operator&&(long4 p, long4 q) +{ + return long4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline long2 operator&&(long2 p, long q) +{ + return long2(p.x && q, p.y && q); +} +static inline long3 operator&&(long3 p, long q) +{ + return long3(p.x && q, p.y && q, p.z && q); +} +static inline long4 operator&&(long4 p, long q) +{ + return long4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline long2 operator&&(long p, long2 q) +{ + return long2(p && q.x, p && q.y); +} +static inline long3 operator&&(long p, long3 q) +{ + return long3(p && q.x, p && q.y, p && q.z); +} +static inline long4 operator&&(long p, long4 q) +{ + return long4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline long2 operator&&(ulong2 p, ulong2 q) +{ + return long2(p.x && q.x, p.y && q.y); +} +static inline long3 operator&&(ulong3 p, ulong3 q) +{ + return long3(p.x && q.x, p.y && q.y, p.z && q.z); +} +static inline long4 operator&&(ulong4 p, ulong4 q) +{ + return long4(p.x && q.x, p.y && q.y, p.z && q.z, p.w && q.w); +} +static inline long2 operator&&(ulong2 p, ulong q) +{ + return long2(p.x && q, p.y && q); +} +static inline long3 operator&&(ulong3 p, ulong q) +{ + return long3(p.x && q, p.y && q, p.z && q); +} +static inline long4 operator&&(ulong4 p, ulong q) +{ + return long4(p.x && q, p.y && q, p.z && q, p.w && q); +} +static inline long2 operator&&(ulong p, ulong2 q) +{ + return long2(p && q.x, p && q.y); +} +static inline long3 operator&&(ulong p, ulong3 q) +{ + return long3(p && q.x, p && q.y, p && q.z); +} +static inline long4 operator&&(ulong p, ulong4 q) +{ + return long4(p && q.x, p && q.y, p && q.z, p && q.w); +} +static inline int2 operator||(float2 p, float2 q) +{ + return int2(p.x || q.x, p.y || q.y); +} +static inline int3 operator||(float3 p, float3 q) +{ + return int3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline int4 operator||(float4 p, float4 q) +{ + return int4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline int2 operator||(float2 p, float q) +{ + return int2(p.x || q, p.y || q); +} +static inline int3 operator||(float3 p, float q) +{ + return int3(p.x || q, p.y || q, p.z || q); +} +static inline int4 operator||(float4 p, float q) +{ + return int4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline int2 operator||(float p, float2 q) +{ + return int2(p || q.x, p || q.y); +} +static inline int3 operator||(float p, float3 q) +{ + return int3(p || q.x, p || q.y, p || q.z); +} +static inline int4 operator||(float p, float4 q) +{ + return int4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline long2 operator||(double2 p, double2 q) +{ + return long2(p.x || q.x, p.y || q.y); +} +static inline long3 operator||(double3 p, double3 q) +{ + return long3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline long4 operator||(double4 p, double4 q) +{ + return long4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline long2 operator||(double2 p, double q) +{ + return long2(p.x || q, p.y || q); +} +static inline long3 operator||(double3 p, double q) +{ + return long3(p.x || q, p.y || q, p.z || q); +} +static inline long4 operator||(double4 p, double q) +{ + return long4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline long2 operator||(double p, double2 q) +{ + return long2(p || q.x, p || q.y); +} +static inline long3 operator||(double p, double3 q) +{ + return long3(p || q.x, p || q.y, p || q.z); +} +static inline long4 operator||(double p, double4 q) +{ + return long4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline int2 operator||(int2 p, int2 q) +{ + return int2(p.x || q.x, p.y || q.y); +} +static inline int3 operator||(int3 p, int3 q) +{ + return int3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline int4 operator||(int4 p, int4 q) +{ + return int4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline int2 operator||(int2 p, int q) +{ + return int2(p.x || q, p.y || q); +} +static inline int3 operator||(int3 p, int q) +{ + return int3(p.x || q, p.y || q, p.z || q); +} +static inline int4 operator||(int4 p, int q) +{ + return int4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline int2 operator||(int p, int2 q) +{ + return int2(p || q.x, p || q.y); +} +static inline int3 operator||(int p, int3 q) +{ + return int3(p || q.x, p || q.y, p || q.z); +} +static inline int4 operator||(int p, int4 q) +{ + return int4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline int2 operator||(uint2 p, uint2 q) +{ + return int2(p.x || q.x, p.y || q.y); +} +static inline int3 operator||(uint3 p, uint3 q) +{ + return int3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline int4 operator||(uint4 p, uint4 q) +{ + return int4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline int2 operator||(uint2 p, uint q) +{ + return int2(p.x || q, p.y || q); +} +static inline int3 operator||(uint3 p, uint q) +{ + return int3(p.x || q, p.y || q, p.z || q); +} +static inline int4 operator||(uint4 p, uint q) +{ + return int4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline int2 operator||(uint p, uint2 q) +{ + return int2(p || q.x, p || q.y); +} +static inline int3 operator||(uint p, uint3 q) +{ + return int3(p || q.x, p || q.y, p || q.z); +} +static inline int4 operator||(uint p, uint4 q) +{ + return int4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline short2 operator||(short2 p, short2 q) +{ + return short2(p.x || q.x, p.y || q.y); +} +static inline short3 operator||(short3 p, short3 q) +{ + return short3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline short4 operator||(short4 p, short4 q) +{ + return short4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline short2 operator||(short2 p, short q) +{ + return short2(p.x || q, p.y || q); +} +static inline short3 operator||(short3 p, short q) +{ + return short3(p.x || q, p.y || q, p.z || q); +} +static inline short4 operator||(short4 p, short q) +{ + return short4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline short2 operator||(short p, short2 q) +{ + return short2(p || q.x, p || q.y); +} +static inline short3 operator||(short p, short3 q) +{ + return short3(p || q.x, p || q.y, p || q.z); +} +static inline short4 operator||(short p, short4 q) +{ + return short4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline short2 operator||(ushort2 p, ushort2 q) +{ + return short2(p.x || q.x, p.y || q.y); +} +static inline short3 operator||(ushort3 p, ushort3 q) +{ + return short3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline short4 operator||(ushort4 p, ushort4 q) +{ + return short4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline short2 operator||(ushort2 p, ushort q) +{ + return short2(p.x || q, p.y || q); +} +static inline short3 operator||(ushort3 p, ushort q) +{ + return short3(p.x || q, p.y || q, p.z || q); +} +static inline short4 operator||(ushort4 p, ushort q) +{ + return short4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline short2 operator||(ushort p, ushort2 q) +{ + return short2(p || q.x, p || q.y); +} +static inline short3 operator||(ushort p, ushort3 q) +{ + return short3(p || q.x, p || q.y, p || q.z); +} +static inline short4 operator||(ushort p, ushort4 q) +{ + return short4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline long2 operator||(long2 p, long2 q) +{ + return long2(p.x || q.x, p.y || q.y); +} +static inline long3 operator||(long3 p, long3 q) +{ + return long3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline long4 operator||(long4 p, long4 q) +{ + return long4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline long2 operator||(long2 p, long q) +{ + return long2(p.x || q, p.y || q); +} +static inline long3 operator||(long3 p, long q) +{ + return long3(p.x || q, p.y || q, p.z || q); +} +static inline long4 operator||(long4 p, long q) +{ + return long4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline long2 operator||(long p, long2 q) +{ + return long2(p || q.x, p || q.y); +} +static inline long3 operator||(long p, long3 q) +{ + return long3(p || q.x, p || q.y, p || q.z); +} +static inline long4 operator||(long p, long4 q) +{ + return long4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline long2 operator||(ulong2 p, ulong2 q) +{ + return long2(p.x || q.x, p.y || q.y); +} +static inline long3 operator||(ulong3 p, ulong3 q) +{ + return long3(p.x || q.x, p.y || q.y, p.z || q.z); +} +static inline long4 operator||(ulong4 p, ulong4 q) +{ + return long4(p.x || q.x, p.y || q.y, p.z || q.z, p.w || q.w); +} +static inline long2 operator||(ulong2 p, ulong q) +{ + return long2(p.x || q, p.y || q); +} +static inline long3 operator||(ulong3 p, ulong q) +{ + return long3(p.x || q, p.y || q, p.z || q); +} +static inline long4 operator||(ulong4 p, ulong q) +{ + return long4(p.x || q, p.y || q, p.z || q, p.w || q); +} +static inline long2 operator||(ulong p, ulong2 q) +{ + return long2(p || q.x, p || q.y); +} +static inline long3 operator||(ulong p, ulong3 q) +{ + return long3(p || q.x, p || q.y, p || q.z); +} +static inline long4 operator||(ulong p, ulong4 q) +{ + return long4(p || q.x, p || q.y, p || q.z, p || q.w); +} +static inline float2 convert_float2(float2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(float3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(float4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(double2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(double3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(double4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(int2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(int3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(int4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(uint2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(uint3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(uint4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(short2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(short3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(short4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(ushort2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(ushort3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(ushort4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(long2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(long3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(long4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline float2 convert_float2(ulong2 p) +{ + return float2((float)p.x, (float)p.y); +} +static inline float3 convert_float3(ulong3 p) +{ + return float3((float)p.x, (float)p.y, (float)p.z); +} +static inline float4 convert_float4(ulong4 p) +{ + return float4((float)p.x, (float)p.y, (float)p.z, (float)p.w); +} +static inline double2 convert_double2(float2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(float3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(float4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(double2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(double3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(double4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(int2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(int3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(int4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(uint2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(uint3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(uint4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(short2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(short3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(short4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(ushort2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(ushort3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(ushort4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(long2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(long3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(long4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline double2 convert_double2(ulong2 p) +{ + return double2((double)p.x, (double)p.y); +} +static inline double3 convert_double3(ulong3 p) +{ + return double3((double)p.x, (double)p.y, (double)p.z); +} +static inline double4 convert_double4(ulong4 p) +{ + return double4((double)p.x, (double)p.y, (double)p.z, (double)p.w); +} +static inline int2 convert_int2(float2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(float3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(float4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(double2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(double3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(double4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(int2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(int3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(int4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(uint2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(uint3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(uint4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(short2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(short3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(short4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(ushort2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(ushort3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(ushort4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(long2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(long3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(long4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline int2 convert_int2(ulong2 p) +{ + return int2((int)p.x, (int)p.y); +} +static inline int3 convert_int3(ulong3 p) +{ + return int3((int)p.x, (int)p.y, (int)p.z); +} +static inline int4 convert_int4(ulong4 p) +{ + return int4((int)p.x, (int)p.y, (int)p.z, (int)p.w); +} +static inline uint2 convert_uint2(float2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(float3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(float4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(double2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(double3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(double4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(int2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(int3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(int4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(uint2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(uint3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(uint4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(short2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(short3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(short4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(ushort2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(ushort3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(ushort4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(long2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(long3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(long4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline uint2 convert_uint2(ulong2 p) +{ + return uint2((uint) p.x, (uint) p.y); +} +static inline uint3 convert_uint3(ulong3 p) +{ + return uint3((uint) p.x, (uint) p.y, (uint) p.z); +} +static inline uint4 convert_uint4(ulong4 p) +{ + return uint4((uint) p.x, (uint) p.y, (uint) p.z, (uint) p.w); +} +static inline short2 convert_short2(float2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(float3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(float4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(double2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(double3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(double4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(int2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(int3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(int4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(uint2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(uint3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(uint4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(short2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(short3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(short4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(ushort2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(ushort3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(ushort4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(long2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(long3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(long4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline short2 convert_short2(ulong2 p) +{ + return short2((short)p.x, (short)p.y); +} +static inline short3 convert_short3(ulong3 p) +{ + return short3((short)p.x, (short)p.y, (short)p.z); +} +static inline short4 convert_short4(ulong4 p) +{ + return short4((short)p.x, (short)p.y, (short)p.z, (short)p.w); +} +static inline ushort2 convert_ushort2(float2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(float3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(float4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(double2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(double3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(double4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(int2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(int3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(int4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(uint2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(uint3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(uint4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(short2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(short3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(short4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(ushort2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(ushort3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(ushort4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(long2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(long3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(long4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline ushort2 convert_ushort2(ulong2 p) +{ + return ushort2((ushort) p.x, (ushort) p.y); +} +static inline ushort3 convert_ushort3(ulong3 p) +{ + return ushort3((ushort) p.x, (ushort) p.y, (ushort) p.z); +} +static inline ushort4 convert_ushort4(ulong4 p) +{ + return ushort4((ushort) p.x, (ushort) p.y, (ushort) p.z, (ushort) p.w); +} +static inline long2 convert_long2(float2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(float3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(float4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(double2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(double3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(double4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(int2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(int3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(int4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(uint2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(uint3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(uint4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(short2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(short3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(short4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(ushort2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(ushort3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(ushort4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(long2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(long3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(long4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline long2 convert_long2(ulong2 p) +{ + return long2((long)p.x, (long)p.y); +} +static inline long3 convert_long3(ulong3 p) +{ + return long3((long)p.x, (long)p.y, (long)p.z); +} +static inline long4 convert_long4(ulong4 p) +{ + return long4((long)p.x, (long)p.y, (long)p.z, (long)p.w); +} +static inline ulong2 convert_ulong2(float2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(float3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(float4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(double2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(double3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(double4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(int2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(int3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(int4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(uint2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(uint3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(uint4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(short2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(short3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(short4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(ushort2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(ushort3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(ushort4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(long2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(long3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(long4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline ulong2 convert_ulong2(ulong2 p) +{ + return ulong2((ulong) p.x, (ulong) p.y); +} +static inline ulong3 convert_ulong3(ulong3 p) +{ + return ulong3((ulong) p.x, (ulong) p.y, (ulong) p.z); +} +static inline ulong4 convert_ulong4(ulong4 p) +{ + return ulong4((ulong) p.x, (ulong) p.y, (ulong) p.z, (ulong) p.w); +} +static inline float2 as_float2(float2 inp) +{ + float2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline int2 as_int2(float2 inp) +{ + int2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline uint2 as_uint2(float2 inp) +{ + uint2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline double2 as_double2(double2 inp) +{ + double2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline long2 as_long2(double2 inp) +{ + long2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline ulong2 as_ulong2(double2 inp) +{ + ulong2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline float2 as_float2(int2 inp) +{ + float2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline int2 as_int2(int2 inp) +{ + int2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline uint2 as_uint2(int2 inp) +{ + uint2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline float2 as_float2(uint2 inp) +{ + float2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline int2 as_int2(uint2 inp) +{ + int2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline uint2 as_uint2(uint2 inp) +{ + uint2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline short2 as_short2(short2 inp) +{ + short2 val1; + memcpy(&val1, &inp, 4); + return val1; +} +static inline ushort2 as_ushort2(short2 inp) +{ + ushort2 val1; + memcpy(&val1, &inp, 4); + return val1; +} +static inline short2 as_short2(ushort2 inp) +{ + short2 val1; + memcpy(&val1, &inp, 4); + return val1; +} +static inline ushort2 as_ushort2(ushort2 inp) +{ + ushort2 val1; + memcpy(&val1, &inp, 4); + return val1; +} +static inline double2 as_double2(long2 inp) +{ + double2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline long2 as_long2(long2 inp) +{ + long2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline ulong2 as_ulong2(long2 inp) +{ + ulong2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline double2 as_double2(ulong2 inp) +{ + double2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline long2 as_long2(ulong2 inp) +{ + long2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline ulong2 as_ulong2(ulong2 inp) +{ + ulong2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline short4 as_short4(float2 inp) +{ + short4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline ushort4 as_ushort4(float2 inp) +{ + ushort4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline float4 as_float4(double2 inp) +{ + float4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline int4 as_int4(double2 inp) +{ + int4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline uint4 as_uint4(double2 inp) +{ + uint4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline short4 as_short4(int2 inp) +{ + short4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline ushort4 as_ushort4(int2 inp) +{ + ushort4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline short4 as_short4(uint2 inp) +{ + short4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline ushort4 as_ushort4(uint2 inp) +{ + ushort4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline float4 as_float4(long2 inp) +{ + float4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline int4 as_int4(long2 inp) +{ + int4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline uint4 as_uint4(long2 inp) +{ + uint4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline float4 as_float4(ulong2 inp) +{ + float4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline int4 as_int4(ulong2 inp) +{ + int4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline uint4 as_uint4(ulong2 inp) +{ + uint4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline float3 as_float3(float3 inp) +{ + float3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline int3 as_int3(float3 inp) +{ + int3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline uint3 as_uint3(float3 inp) +{ + uint3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline double3 as_double3(double3 inp) +{ + double3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline long3 as_long3(double3 inp) +{ + long3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline ulong3 as_ulong3(double3 inp) +{ + ulong3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline float3 as_float3(int3 inp) +{ + float3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline int3 as_int3(int3 inp) +{ + int3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline uint3 as_uint3(int3 inp) +{ + uint3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline float3 as_float3(uint3 inp) +{ + float3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline int3 as_int3(uint3 inp) +{ + int3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline uint3 as_uint3(uint3 inp) +{ + uint3 val1; + memcpy(&val1, &inp, 12); + return val1; +} +static inline short3 as_short3(short3 inp) +{ + short3 val1; + memcpy(&val1, &inp, 6); + return val1; +} +static inline ushort3 as_ushort3(short3 inp) +{ + ushort3 val1; + memcpy(&val1, &inp, 6); + return val1; +} +static inline short3 as_short3(ushort3 inp) +{ + short3 val1; + memcpy(&val1, &inp, 6); + return val1; +} +static inline ushort3 as_ushort3(ushort3 inp) +{ + ushort3 val1; + memcpy(&val1, &inp, 6); + return val1; +} +static inline double3 as_double3(long3 inp) +{ + double3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline long3 as_long3(long3 inp) +{ + long3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline ulong3 as_ulong3(long3 inp) +{ + ulong3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline double3 as_double3(ulong3 inp) +{ + double3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline long3 as_long3(ulong3 inp) +{ + long3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline ulong3 as_ulong3(ulong3 inp) +{ + ulong3 val1; + memcpy(&val1, &inp, 24); + return val1; +} +static inline double2 as_double2(float4 inp) +{ + double2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline long2 as_long2(float4 inp) +{ + long2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline ulong2 as_ulong2(float4 inp) +{ + ulong2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline double2 as_double2(int4 inp) +{ + double2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline long2 as_long2(int4 inp) +{ + long2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline ulong2 as_ulong2(int4 inp) +{ + ulong2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline double2 as_double2(uint4 inp) +{ + double2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline long2 as_long2(uint4 inp) +{ + long2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline ulong2 as_ulong2(uint4 inp) +{ + ulong2 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline float2 as_float2(short4 inp) +{ + float2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline int2 as_int2(short4 inp) +{ + int2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline uint2 as_uint2(short4 inp) +{ + uint2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline float2 as_float2(ushort4 inp) +{ + float2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline int2 as_int2(ushort4 inp) +{ + int2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline uint2 as_uint2(ushort4 inp) +{ + uint2 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline float4 as_float4(float4 inp) +{ + float4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline int4 as_int4(float4 inp) +{ + int4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline uint4 as_uint4(float4 inp) +{ + uint4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline double4 as_double4(double4 inp) +{ + double4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline long4 as_long4(double4 inp) +{ + long4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline ulong4 as_ulong4(double4 inp) +{ + ulong4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline float4 as_float4(int4 inp) +{ + float4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline int4 as_int4(int4 inp) +{ + int4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline uint4 as_uint4(int4 inp) +{ + uint4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline float4 as_float4(uint4 inp) +{ + float4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline int4 as_int4(uint4 inp) +{ + int4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline uint4 as_uint4(uint4 inp) +{ + uint4 val1; + memcpy(&val1, &inp, 16); + return val1; +} +static inline short4 as_short4(short4 inp) +{ + short4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline ushort4 as_ushort4(short4 inp) +{ + ushort4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline short4 as_short4(ushort4 inp) +{ + short4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline ushort4 as_ushort4(ushort4 inp) +{ + ushort4 val1; + memcpy(&val1, &inp, 8); + return val1; +} +static inline double4 as_double4(long4 inp) +{ + double4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline long4 as_long4(long4 inp) +{ + long4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline ulong4 as_ulong4(long4 inp) +{ + ulong4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline double4 as_double4(ulong4 inp) +{ + double4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline long4 as_long4(ulong4 inp) +{ + long4 val1; + memcpy(&val1, &inp, 32); + return val1; +} +static inline ulong4 as_ulong4(ulong4 inp) +{ + ulong4 val1; + memcpy(&val1, &inp, 32); + return val1; +} + +#define xx xx() +#define xy xy() +#define xz xz() +#define xw xw() +#define yx yx() +#define yy yy() +#define yz yz() +#define yw yw() +#define zx zx() +#define zy zy() +#define zz zz() +#define zw zw() +#define wx wx() +#define wy wy() +#define wz wz() +#define ww ww() +#define xxx xxx() +#define xxy xxy() +#define xxz xxz() +#define xxw xxw() +#define xyx xyx() +#define xyy xyy() +#define xyz xyz() +#define xyw xyw() +#define xzx xzx() +#define xzy xzy() +#define xzz xzz() +#define xzw xzw() +#define xwx xwx() +#define xwy xwy() +#define xwz xwz() +#define xww xww() +#define yxx yxx() +#define yxy yxy() +#define yxz yxz() +#define yxw yxw() +#define yyx yyx() +#define yyy yyy() +#define yyz yyz() +#define yyw yyw() +#define yzx yzx() +#define yzy yzy() +#define yzz yzz() +#define yzw yzw() +#define ywx ywx() +#define ywy ywy() +#define ywz ywz() +#define yww yww() +#define zxx zxx() +#define zxy zxy() +#define zxz zxz() +#define zxw zxw() +#define zyx zyx() +#define zyy zyy() +#define zyz zyz() +#define zyw zyw() +#define zzx zzx() +#define zzy zzy() +#define zzz zzz() +#define zzw zzw() +#define zwx zwx() +#define zwy zwy() +#define zwz zwz() +#define zww zww() +#define wxx wxx() +#define wxy wxy() +#define wxz wxz() +#define wxw wxw() +#define wyx wyx() +#define wyy wyy() +#define wyz wyz() +#define wyw wyw() +#define wzx wzx() +#define wzy wzy() +#define wzz wzz() +#define wzw wzw() +#define wwx wwx() +#define wwy wwy() +#define wwz wwz() +#define www www() +#define xxxx xxxx() +#define xxxy xxxy() +#define xxxz xxxz() +#define xxxw xxxw() +#define xxyx xxyx() +#define xxyy xxyy() +#define xxyz xxyz() +#define xxyw xxyw() +#define xxzx xxzx() +#define xxzy xxzy() +#define xxzz xxzz() +#define xxzw xxzw() +#define xxwx xxwx() +#define xxwy xxwy() +#define xxwz xxwz() +#define xxww xxww() +#define xyxx xyxx() +#define xyxy xyxy() +#define xyxz xyxz() +#define xyxw xyxw() +#define xyyx xyyx() +#define xyyy xyyy() +#define xyyz xyyz() +#define xyyw xyyw() +#define xyzx xyzx() +#define xyzy xyzy() +#define xyzz xyzz() +#define xyzw xyzw() +#define xywx xywx() +#define xywy xywy() +#define xywz xywz() +#define xyww xyww() +#define xzxx xzxx() +#define xzxy xzxy() +#define xzxz xzxz() +#define xzxw xzxw() +#define xzyx xzyx() +#define xzyy xzyy() +#define xzyz xzyz() +#define xzyw xzyw() +#define xzzx xzzx() +#define xzzy xzzy() +#define xzzz xzzz() +#define xzzw xzzw() +#define xzwx xzwx() +#define xzwy xzwy() +#define xzwz xzwz() +#define xzww xzww() +#define xwxx xwxx() +#define xwxy xwxy() +#define xwxz xwxz() +#define xwxw xwxw() +#define xwyx xwyx() +#define xwyy xwyy() +#define xwyz xwyz() +#define xwyw xwyw() +#define xwzx xwzx() +#define xwzy xwzy() +#define xwzz xwzz() +#define xwzw xwzw() +#define xwwx xwwx() +#define xwwy xwwy() +#define xwwz xwwz() +#define xwww xwww() +#define yxxx yxxx() +#define yxxy yxxy() +#define yxxz yxxz() +#define yxxw yxxw() +#define yxyx yxyx() +#define yxyy yxyy() +#define yxyz yxyz() +#define yxyw yxyw() +#define yxzx yxzx() +#define yxzy yxzy() +#define yxzz yxzz() +#define yxzw yxzw() +#define yxwx yxwx() +#define yxwy yxwy() +#define yxwz yxwz() +#define yxww yxww() +#define yyxx yyxx() +#define yyxy yyxy() +#define yyxz yyxz() +#define yyxw yyxw() +#define yyyx yyyx() +#define yyyy yyyy() +#define yyyz yyyz() +#define yyyw yyyw() +#define yyzx yyzx() +#define yyzy yyzy() +#define yyzz yyzz() +#define yyzw yyzw() +#define yywx yywx() +#define yywy yywy() +#define yywz yywz() +#define yyww yyww() +#define yzxx yzxx() +#define yzxy yzxy() +#define yzxz yzxz() +#define yzxw yzxw() +#define yzyx yzyx() +#define yzyy yzyy() +#define yzyz yzyz() +#define yzyw yzyw() +#define yzzx yzzx() +#define yzzy yzzy() +#define yzzz yzzz() +#define yzzw yzzw() +#define yzwx yzwx() +#define yzwy yzwy() +#define yzwz yzwz() +#define yzww yzww() +#define ywxx ywxx() +#define ywxy ywxy() +#define ywxz ywxz() +#define ywxw ywxw() +#define ywyx ywyx() +#define ywyy ywyy() +#define ywyz ywyz() +#define ywyw ywyw() +#define ywzx ywzx() +#define ywzy ywzy() +#define ywzz ywzz() +#define ywzw ywzw() +#define ywwx ywwx() +#define ywwy ywwy() +#define ywwz ywwz() +#define ywww ywww() +#define zxxx zxxx() +#define zxxy zxxy() +#define zxxz zxxz() +#define zxxw zxxw() +#define zxyx zxyx() +#define zxyy zxyy() +#define zxyz zxyz() +#define zxyw zxyw() +#define zxzx zxzx() +#define zxzy zxzy() +#define zxzz zxzz() +#define zxzw zxzw() +#define zxwx zxwx() +#define zxwy zxwy() +#define zxwz zxwz() +#define zxww zxww() +#define zyxx zyxx() +#define zyxy zyxy() +#define zyxz zyxz() +#define zyxw zyxw() +#define zyyx zyyx() +#define zyyy zyyy() +#define zyyz zyyz() +#define zyyw zyyw() +#define zyzx zyzx() +#define zyzy zyzy() +#define zyzz zyzz() +#define zyzw zyzw() +#define zywx zywx() +#define zywy zywy() +#define zywz zywz() +#define zyww zyww() +#define zzxx zzxx() +#define zzxy zzxy() +#define zzxz zzxz() +#define zzxw zzxw() +#define zzyx zzyx() +#define zzyy zzyy() +#define zzyz zzyz() +#define zzyw zzyw() +#define zzzx zzzx() +#define zzzy zzzy() +#define zzzz zzzz() +#define zzzw zzzw() +#define zzwx zzwx() +#define zzwy zzwy() +#define zzwz zzwz() +#define zzww zzww() +#define zwxx zwxx() +#define zwxy zwxy() +#define zwxz zwxz() +#define zwxw zwxw() +#define zwyx zwyx() +#define zwyy zwyy() +#define zwyz zwyz() +#define zwyw zwyw() +#define zwzx zwzx() +#define zwzy zwzy() +#define zwzz zwzz() +#define zwzw zwzw() +#define zwwx zwwx() +#define zwwy zwwy() +#define zwwz zwwz() +#define zwww zwww() +#define wxxx wxxx() +#define wxxy wxxy() +#define wxxz wxxz() +#define wxxw wxxw() +#define wxyx wxyx() +#define wxyy wxyy() +#define wxyz wxyz() +#define wxyw wxyw() +#define wxzx wxzx() +#define wxzy wxzy() +#define wxzz wxzz() +#define wxzw wxzw() +#define wxwx wxwx() +#define wxwy wxwy() +#define wxwz wxwz() +#define wxww wxww() +#define wyxx wyxx() +#define wyxy wyxy() +#define wyxz wyxz() +#define wyxw wyxw() +#define wyyx wyyx() +#define wyyy wyyy() +#define wyyz wyyz() +#define wyyw wyyw() +#define wyzx wyzx() +#define wyzy wyzy() +#define wyzz wyzz() +#define wyzw wyzw() +#define wywx wywx() +#define wywy wywy() +#define wywz wywz() +#define wyww wyww() +#define wzxx wzxx() +#define wzxy wzxy() +#define wzxz wzxz() +#define wzxw wzxw() +#define wzyx wzyx() +#define wzyy wzyy() +#define wzyz wzyz() +#define wzyw wzyw() +#define wzzx wzzx() +#define wzzy wzzy() +#define wzzz wzzz() +#define wzzw wzzw() +#define wzwx wzwx() +#define wzwy wzwy() +#define wzwz wzwz() +#define wzww wzww() +#define wwxx wwxx() +#define wwxy wwxy() +#define wwxz wwxz() +#define wwxw wwxw() +#define wwyx wwyx() +#define wwyy wwyy() +#define wwyz wwyz() +#define wwyw wwyw() +#define wwzx wwzx() +#define wwzy wwzy() +#define wwzz wwzz() +#define wwzw wwzw() +#define wwwx wwwx() +#define wwwy wwwy() +#define wwwz wwwz() +#define wwww wwww() diff --git a/third_party/astcenc/Source/win32-2013/astcenc/astcenc.sln b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.sln new file mode 100644 index 0000000000..42af6eb664 --- /dev/null +++ b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astcenc", "astcenc.vcxproj", "{D6D60D86-0502-446A-8498-888F78B869C2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D6D60D86-0502-446A-8498-888F78B869C2}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6D60D86-0502-446A-8498-888F78B869C2}.Debug|Win32.Build.0 = Debug|Win32 + {D6D60D86-0502-446A-8498-888F78B869C2}.Debug|x64.ActiveCfg = Debug|x64 + {D6D60D86-0502-446A-8498-888F78B869C2}.Debug|x64.Build.0 = Debug|x64 + {D6D60D86-0502-446A-8498-888F78B869C2}.Release|Win32.ActiveCfg = Release|Win32 + {D6D60D86-0502-446A-8498-888F78B869C2}.Release|Win32.Build.0 = Release|Win32 + {D6D60D86-0502-446A-8498-888F78B869C2}.Release|x64.ActiveCfg = Release|x64 + {D6D60D86-0502-446A-8498-888F78B869C2}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcproj b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcproj new file mode 100644 index 0000000000..49abab23ee --- /dev/null +++ b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcproj @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcxproj b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcxproj new file mode 100644 index 0000000000..8149230623 --- /dev/null +++ b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcxproj @@ -0,0 +1,193 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D6D60D86-0502-446A-8498-888F78B869C2} + astcenc + Win32Proj + + + + Application + Unicode + true + v120 + + + Application + Unicode + true + v120 + + + Application + Unicode + v120 + + + Application + Unicode + v120 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + false + + + + Disabled + $(ProjectDir);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + NotSet + + + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + Disabled + $(ProjectDir);%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + NotSet + + + Level3 + ProgramDatabase + + + true + Console + + + + + $(ProjectDir);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + NotSet + Precise + + + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + $(ProjectDir);%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + NotSet + Precise + + + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcxproj.filters b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcxproj.filters new file mode 100644 index 0000000000..33653ff011 --- /dev/null +++ b/third_party/astcenc/Source/win32-2013/astcenc/astcenc.vcxproj.filters @@ -0,0 +1,114 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/third_party/astcenc/Source/win32-2013/astcenc/stdint.h b/third_party/astcenc/Source/win32-2013/astcenc/stdint.h new file mode 100644 index 0000000000..8b5f7f94ef --- /dev/null +++ b/third_party/astcenc/Source/win32-2013/astcenc/stdint.h @@ -0,0 +1,33 @@ +/*----------------------------------------------------------------------------*/ +/** + * This confidential and proprietary software may be used only as + * authorised by a licensing agreement from ARM Limited + * (C) COPYRIGHT 2011-2012 ARM Limited + * ALL RIGHTS RESERVED + * + * The entire notice above must be reproduced on all authorised + * copies and copies may only be made to the extent permitted + * by a licensing agreement from ARM Limited. + * + * @brief Replacement for missing stdint.h for use in Visual Studio only. + */ +/*----------------------------------------------------------------------------*/ + +#ifndef _stdint_h_ + +typedef unsigned char uint8_t; +typedef signed char int8_t; + +typedef unsigned short uint16_t; +typedef signed short int16_t; + +typedef unsigned int uint32_t; +typedef signed int int32_t; + +typedef unsigned long long uint64_t; +typedef signed long long int64_t; + +#define __func__ "Function name unavailable" +#define M_PI 3.14159265358979323846264338 + +#endif \ No newline at end of file diff --git a/third_party/astcenc/include/astcenc.h b/third_party/astcenc/include/astcenc.h new file mode 100644 index 0000000000..862082be11 --- /dev/null +++ b/third_party/astcenc/include/astcenc.h @@ -0,0 +1,116 @@ +// ------------------------------------------------------------------------------------------------- +// This file declares the minimum amount of constants, enums, structs, and functions that are needed +// when interfacing with astcenc, which has no public-facing header files. To see how to use this +// interface, see astc_toplevel.cpp +// ------------------------------------------------------------------------------------------------- + +#pragma once + +#include + +#define MAX_TEXELS_PER_BLOCK 216 +#define PARTITION_BITS 10 +#define PARTITION_COUNT (1 << PARTITION_BITS) + +enum astc_decode_mode { + DECODE_LDR_SRGB, + DECODE_LDR, + DECODE_HDR +}; + +struct astc_codec_image { + uint8_t*** imagedata8; + uint16_t*** imagedata16; + int xsize; + int ysize; + int zsize; + int padding; +}; + +struct error_weighting_params { + float rgb_power; + float rgb_base_weight; + float rgb_mean_weight; + float rgb_stdev_weight; + float alpha_power; + float alpha_base_weight; + float alpha_mean_weight; + float alpha_stdev_weight; + float rgb_mean_and_stdev_mixing; + int mean_stdev_radius; + int enable_rgb_scale_with_alpha; + int alpha_radius; + int ra_normal_angular_scale; + float block_artifact_suppression; + float rgba_weights[4]; + float block_artifact_suppression_expanded[MAX_TEXELS_PER_BLOCK]; + int partition_search_limit; + float block_mode_cutoff; + float texel_avg_error_limit; + float partition_1_to_2_limit; + float lowest_correlation_cutoff; + int max_refinement_iters; +}; + +struct swizzlepattern { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +}; + +typedef uint16_t sf16; +typedef uint32_t sf32; + +enum roundmode { + SF_UP = 0, + SF_DOWN = 1, + SF_TOZERO = 2, + SF_NEARESTEVEN = 3, + SF_NEARESTAWAY = 4 +}; + +extern void encode_astc_image( + const astc_codec_image* input_image, + astc_codec_image* output_image, + int xdim, + int ydim, + int zdim, + const error_weighting_params* ewp, + astc_decode_mode decode_mode, + swizzlepattern swz_encode, + swizzlepattern swz_decode, + uint8_t* buffer, + int pack_and_unpack, + int threadcount); + +extern void expand_block_artifact_suppression( + int xdim, + int ydim, + int zdim, + error_weighting_params* ewp); + +extern void find_closest_blockdim_2d( + float target_bitrate, + int *x, + int *y, + int consider_illegal); + +extern void find_closest_blockdim_3d( + float target_bitrate, + int *x, + int *y, + int *z, + int consider_illegal); + +extern void destroy_image(astc_codec_image* img); + +extern astc_codec_image* allocate_image(int bitness, int xsize, int ysize, int zsize, int padding); + +extern void test_inappropriate_extended_precision(); +extern void prepare_angular_tables(); +extern void build_quantization_mode_table(); + +extern "C" { + sf16 float_to_sf16(float, roundmode); +} diff --git a/third_party/astcenc/license.txt b/third_party/astcenc/license.txt new file mode 100644 index 0000000000..a33bccd57e --- /dev/null +++ b/third_party/astcenc/license.txt @@ -0,0 +1,137 @@ +END USER LICENCE AGREEMENT FOR THE MALI ASTC SPECIFICATION AND SOFTWARE CODEC, +VERSION: 1.3 + +THIS END USER LICENCE AGREEMENT ("LICENCE") IS A LEGAL AGREEMENT BETWEEN YOU +(EITHER A SINGLE INDIVIDUAL, OR SINGLE LEGAL ENTITY) AND ARM LIMITED ("ARM") +FOR THE USE OF THE SOFTWARE ACCOMPANYING THIS LICENCE. ARM IS ONLY WILLING +TO LICENSE THE SOFTWARE TO YOU ON CONDITION THAT YOU ACCEPT ALL OF THE TERMS +IN THIS LICENCE. BY CLICKING "I AGREE" OR BY INSTALLING OR OTHERWISE USING +OR COPYING THE SOFTWARE YOU INDICATE THAT YOU AGREE TO BE BOUND BY ALL THE +TERMS OF THIS LICENCE. + +IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENCE, ARM IS UNWILLING TO LICENSE +THE SOFTWARE TO YOU AND YOU MAY NOT INSTALL, USE OR COPY THE SOFTWARE. + +1. DEFINITIONS. + +"Authorised Purpose" means the use of the Software solely to develop products +and tools which implement the Khronos ASTC specification to; +(i) compress texture images into ASTC format ("Compression Results"); +(ii) distribute such Compression Results to third parties; and +(iii) decompress texture images stored in ASTC format. + +"Software" means the source code and Software binaries accompanying this +Licence, and any printed, electronic or online documentation supplied with it, +in all cases relating to the MALI ASTC SPECIFICATION AND SOFTWARE CODEC. + +2. LICENCE GRANT. + +ARM hereby grants to you, subject to the terms and conditions of this Licence, +a nonexclusive, nontransferable, free of charge, royalty free, worldwide +licence to use, copy, modify and (subject to Clause 3 below) distribute the +Software solely for the Authorised Purpose. + +No right is granted to use the Software to develop hardware. + +Notwithstanding the foregoing, nothing in this Licence prevents you from +using the Software to develop products that conform to an application +programming interface specification issued by The Khronos Group Inc. +("Khronos"), provided that you have licences to develop such products +under the relevant Khronos agreements. + + 3. RESTRICTIONS ON USE OF THE SOFTWARE. + +RESTRICTIONS ON TRANSFER OF LICENSED RIGHTS: The rights granted to you under +this Licence may not be assigned by you to any third party without the prior +written consent of ARM. + +TITLE AND RESERVATION OF RIGHTS: You acquire no rights to the Software other +than as expressly provided by this Licence. The Software is licensed not sold. +ARM does not transfer title to the Software to you. In no event shall the +licences granted in Clause 2 be construed as granting you expressly or by +implication, estoppel or otherwise, licences to any ARM technology other than +the Software. + +NOTICES: You shall not remove from the Software any copyright notice or other +notice (whether ARM's or its licensor's), and you shall ensure that any such +notice is reproduced in any copies of the whole or any part of the Software +made by you. You shall not use ARM's or its licensor's name, logo or +trademarks to market Compression Results. If you distribute the Software to a +third party, you agree to include a copy of this Licence with such +distribution. + +4. NO SUPPORT. + +ARM has no obligation to support or to continue providing or updating any of +the Software. + +5. NO WARRANTIES. + +YOU AGREE THAT THE SOFTWARE IS LICENSED "AS IS", AND THAT ARM EXPRESSLY +DISCLAIMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS OR OTHER TERMS, EXPRESS, +IMPLIED OR STATUTORY, TO THE FULLEST EXTENT PERMITTED BY LAW. YOU EXPRESSLY +ASSUME ALL LIABILITIES AND RISKS, FOR USE OR OPERATION OF ANY APPLICATION +PROGRAMS YOU CREATE WITH THE SOFTWARE, AND YOU ASSUME THE ENTIRE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +6. LIMITATION OF LIABILITY. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL ARM BE +LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +(INCLUDING LOSS OF PROFITS) ARISING OUT OF THE USE OR INABILITY TO USE THE +SOFTWARE WHETHER BASED ON A CLAIM UNDER CONTRACT, TORT OR OTHER LEGAL THEORY, +EVEN IF ARM WAS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +ARM does not seek to limit or exclude liability for death or personal injury +arising from ARM's negligence and because some jurisdictions do not permit the +exclusion or limitation of liability for consequential or incidental damages +the above limitation relating to liability for consequential damages may not +apply to you. + +NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED IN THIS LICENCE, THE +MAXIMUM LIABILITY OF ARM TO YOU IN AGGREGATE FOR ALL CLAIMS MADE AGAINST ARM +IN CONTRACT TORT OR OTHERWISE UNDER OR IN CONNECTION WITH THE SUBJECT MATTER +OF THIS LICENCE SHALL NOT EXCEED THE GREATER OF THE TOTAL OF SUMS PAID BY YOU +TO ARM (IF ANY) FOR THIS LICENCE AND US$5.00. + +7. U.S. GOVERNMENT END USERS. + +US Government Restrictions: Use, duplication, reproduction, release, +modification, disclosure or transfer of this commercial product and +accompanying documentation is restricted in accordance with the terms +of this Licence. + +8. TERM AND TERMINATION. + +This Licence shall remain in force until terminated by you or by ARM. Without +prejudice to any of its other rights if you are in breach of any of the terms +and conditions of this Licence then ARM may terminate this Licence immediately +upon giving written notice to you. You may terminate this Licence at any time. + +Upon termination of this Licence by you or by ARM you shall stop using the +Software and destroy all copies of the Software in your possession together +with all documentation and related materials. The provisions of Clauses 1, 3, +4, 5, 6, 7, 8 and 9 shall survive termination of this Licence. + +9. GENERAL. + +This Licence is governed by English Law. Except where ARM agrees otherwise in +a written contract signed by you and ARM, this is the only agreement between +you and ARM relating to the Software and it may only be modified by written +agreement between you and ARM. Except as expressly agreed in writing, this +Licence may not be modified by purchase orders, advertising or other +representation by any person. If any clause in this Licence is held by a court +of law to be illegal or unenforceable the remaining provisions of this Licence +shall not be affected thereby. The failure by ARM to enforce any of the +provisions of this Licence, unless waived in writing, shall not constitute a +waiver of ARM's rights to enforce such provision or any other provision of +this Licence in the future. + +You agree to comply fully with all laws and regulations of the United States +and other countries ("Export Laws") to assure that the Software is not; +(1) exported, directly or indirectly, in violation of Export Laws, either to +any countries that are subject to U.S.A. export restrictions or to any end +user who has been prohibited from participating in the U.S.A. export +transactions by any federal agency of the U.S.A. government; or +(2) intended to be used for any purpose prohibited by Export Laws, including, +without limitation, nuclear, chemical, or biological weapons proliferation. diff --git a/third_party/astcenc/tnt/CMakeLists.txt b/third_party/astcenc/tnt/CMakeLists.txt new file mode 100644 index 0000000000..51d95dc605 --- /dev/null +++ b/third_party/astcenc/tnt/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.1) +project(astcenc) + +set(TARGET astcenc) + +set(SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}/../Source") +set(HDRDIR "${CMAKE_CURRENT_SOURCE_DIR}/../include") + +set(SOURCES + ${SRCDIR}/astc_averages_and_directions.cpp + ${SRCDIR}/astc_block_sizes2.cpp + ${SRCDIR}/astc_color_quantize.cpp + ${SRCDIR}/astc_color_unquantize.cpp + ${SRCDIR}/astc_compress_symbolic.cpp + ${SRCDIR}/astc_decompress_symbolic.cpp + ${SRCDIR}/astc_encoding_choice_error.cpp + ${SRCDIR}/astc_find_best_partitioning.cpp + ${SRCDIR}/astc_ideal_endpoints_and_weights.cpp + ${SRCDIR}/astc_image_load_store.cpp + ${SRCDIR}/astc_integer_sequence.cpp + ${SRCDIR}/astc_ktx_dds.cpp + ${SRCDIR}/astc_kmeans_partitioning.cpp + ${SRCDIR}/astc_partition_tables.cpp + ${SRCDIR}/astc_percentile_tables.cpp + ${SRCDIR}/astc_pick_best_endpoint_format.cpp + ${SRCDIR}/astc_quantization.cpp + ${SRCDIR}/astc_stb_tga.cpp + ${SRCDIR}/astc_toplevel.cpp + ${SRCDIR}/astc_symbolic_physical.cpp + ${SRCDIR}/astc_weight_align.cpp + ${SRCDIR}/astc_weight_quant_xfer_tables.cpp + ${SRCDIR}/astc_compute_variance.cpp + ${SRCDIR}/mathlib.cpp + ${SRCDIR}/softfloat.cpp + ${SRCDIR}/astc_codec_internals.h + ${SRCDIR}/mathlib.h + ${SRCDIR}/softfloat.h +) + +add_definitions(-Wno-tautological-compare) + +add_library(${TARGET} STATIC ${SOURCES}) + +target_link_libraries(${TARGET} LINK_PUBLIC stb) + +target_include_directories (${TARGET} PUBLIC ${HDRDIR}) diff --git a/third_party/astcenc/tnt/README b/third_party/astcenc/tnt/README new file mode 100644 index 0000000000..462ef038d1 --- /dev/null +++ b/third_party/astcenc/tnt/README @@ -0,0 +1,25 @@ +This folder was created as follows: + +# +# Fetch and unpack. +# +curl -L -O https://github.com/ARM-software/astc-encoder/archive/a47b80f.zip +unzip a47b80f.zip +mv astc-encoder-* astcenc +cd astcenc + +# +# Perform modifications. +# +rm -rf Binary Documentation +mv license.txt LICENSE +rm Source/stb_image.c Source/imgdiff.cpp +sed -i "" 's/stb_image.c/stb_image.h/g' Source/astc_stb_tga.cpp +sed -i "" 's/main/standalone_main/g' Source/astc_toplevel.cpp + +# +# Copy modified source into the Filament repo. +# +rsync -r ./ ~/github/filament/third_party/astcenc/ --delete --exclude tnt + +Also note that we created the public-facing "include/astcenc.h" file. diff --git a/tools/mipgen/CMakeLists.txt b/tools/mipgen/CMakeLists.txt index 999d61fec8..a15b17227c 100644 --- a/tools/mipgen/CMakeLists.txt +++ b/tools/mipgen/CMakeLists.txt @@ -17,7 +17,7 @@ target_link_libraries(${TARGET} PRIVATE math utils z image imageio getopt) # ================================================================================================= # Licenses # ================================================================================================== -set(MODULE_LICENSES getopt libpng tinyexr libz) +set(MODULE_LICENSES getopt libpng tinyexr libz astcenc) set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR}/generated) list_licenses(${GENERATION_ROOT}/licenses/licenses.inc ${MODULE_LICENSES}) target_include_directories(${TARGET} PRIVATE ${GENERATION_ROOT})