├── .gitignore ├── LICENSE ├── README.md ├── meson.build ├── src ├── hydrium.c ├── include │ └── libhydrium │ │ └── libhydrium.h └── libhydrium │ ├── bitwriter.c │ ├── bitwriter.h │ ├── cluster-map.c │ ├── encoder.c │ ├── encoder.h │ ├── entropy.c │ ├── entropy.h │ ├── format.c │ ├── format.h │ ├── internal.h │ ├── libhydrium.c │ ├── math-functions.h │ ├── memory.c │ └── memory.h ├── subprojects └── spng.wrap └── windows-cross.ini /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # Test Files 55 | *.png 56 | *.raw 57 | *.jxl 58 | *.pfm 59 | 60 | # Valgrind dumps 61 | vgcore.* 62 | 63 | # subprojects 64 | subprojects/spng 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023-2024 Leo Izen (Traneptora) 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 7 | 8 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hydrium 2 | Hydrium is a fast, ultra-low-memory, streaming JPEG XL encoder written in portable C. 3 | 4 | At the moment, it is a work-in-progress and it is still in the early stages of development. The API and CLI are unstable and subject to change without notice. 5 | 6 | The design goals of hydrium prioritize streamability and very low memory footprint. By default, libhydrium uses approximately 1.5 megabytes of RAM for images of any size. Tiles can be sent one at a time to the encoder, while will encode them independently. 7 | 8 | Hydrium does not use threading or any platform-specific assembly. It is desgined to be as portable as possible so it can be used on low-power embedded processors. 9 | 10 | Hydrium is named after the fictitious gas from Kenneth Oppel's novel *Airborn,* which is lighter than even Hydrogen. 11 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('hydrium', 'c', 2 | license: ['BSD-2-Clause'], 3 | version : '0.5.0', 4 | default_options: [ 5 | 'debug=false', 6 | 'optimization=s', 7 | 'c_std=c99', 8 | 'warning_level=1', 9 | ], 10 | ) 11 | 12 | cflags = [ 13 | '-DHYDRIUM_INTERNAL_BUILD', 14 | ] 15 | 16 | wanted_cflags = [ 17 | '-Werror=implicit-function-declaration', 18 | '-fPIC', 19 | '-fno-plt', 20 | '-Wformat', 21 | '-Werror=format-security', 22 | '-fvisibility=hidden', 23 | '-ffp-contract=fast', 24 | '-fallow-store-data-races', 25 | '-Wmissing-prototypes', 26 | ] 27 | 28 | ldflags = [] 29 | 30 | wanted_ldflags = [ 31 | 32 | ] 33 | 34 | cc = meson.get_compiler('c') 35 | 36 | cflags += cc.get_supported_arguments(wanted_cflags) 37 | ldflags += cc.get_supported_link_arguments(wanted_ldflags) 38 | 39 | libhydrium_sources = files( 40 | 'src/libhydrium/bitwriter.c', 41 | 'src/libhydrium/cluster-map.c', 42 | 'src/libhydrium/encoder.c', 43 | 'src/libhydrium/entropy.c', 44 | 'src/libhydrium/format.c', 45 | 'src/libhydrium/libhydrium.c', 46 | 'src/libhydrium/memory.c', 47 | ) 48 | 49 | hydrium_sources = files( 50 | 'src/hydrium.c' 51 | ) 52 | 53 | libhydrium_includes = include_directories('src/include') 54 | 55 | libhydrium = library('hydrium', 56 | sources: libhydrium_sources, 57 | soversion : '0', 58 | c_args: cflags, 59 | link_args: ldflags, 60 | install: true, 61 | include_directories: libhydrium_includes, 62 | ) 63 | 64 | libhydrium_dep = declare_dependency(include_directories: libhydrium_includes, link_with: libhydrium) 65 | libspng_dep = dependency('spng', fallback : ['spng', 'spng_dep']) 66 | 67 | hydrium = executable('hydrium', 68 | sources: [hydrium_sources], 69 | link_with: libhydrium, 70 | dependencies: [libhydrium_dep, libspng_dep], 71 | c_args: cflags, 72 | link_args: ldflags, 73 | install: true, 74 | include_directories: libhydrium_includes, 75 | ) 76 | 77 | install_headers('src/include/libhydrium/libhydrium.h', subdir: 'libhydrium') 78 | -------------------------------------------------------------------------------- /src/hydrium.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hydrium basic implementation 3 | */ 4 | 5 | #ifdef _WIN32 6 | #include 7 | #include 8 | #define hyd_isatty(f) _isatty(_fileno(f)) 9 | #else 10 | #define _POSIX_C_SOURCE 1 11 | #include 12 | #define hyd_isatty(f) isatty(fileno(f)) 13 | #endif 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include "libhydrium/libhydrium.h" 24 | 25 | static const char pfm_sig[4] = "PF\n"; 26 | 27 | static void print_usage(const char *argv0) { 28 | fprintf(stderr, "Usage: %s [options] [--] \n", argv0); 29 | fprintf(stderr, "Options:\n"); 30 | fprintf(stderr, " --help Print this message\n"); 31 | fprintf(stderr, " --tile-size=N Use Tile Size Shift = N, valid values are 0, 1, 2, 3\n"); 32 | fprintf(stderr, " Tile dimensions will be 256 * 2^N\n"); 33 | fprintf(stderr, " Larger tiles use more memory but decode faster.\n"); 34 | fprintf(stderr, " (default: N=0)\n"); 35 | fprintf(stderr, " --one-frame Use one frame. Uses more memory but decodes faster.\n"); 36 | fprintf(stderr, " (default: off)\n"); 37 | fprintf(stderr, " --pfm Assume input is PFM (Portable FloatMap)\n"); 38 | fprintf(stderr, " --png Assume input is PNG (Portable Network Graphics)\n"); 39 | fprintf(stderr, " (default: assume PNG unless input filename ends with .pfm)\n"); 40 | fprintf(stderr, " --linear Assume input is in Linear Light\n"); 41 | fprintf(stderr, " (default: assume sRGB transfer, regardless of PNG tags)\n"); 42 | } 43 | 44 | static int init_spng_stream(spng_ctx **ctx, const char **error_msg, FILE *fin, struct spng_ihdr *ihdr) { 45 | 46 | spng_ctx *spng_context = spng_ctx_new(0); 47 | if (!spng_context) { 48 | *error_msg = "couldn't allocate context"; 49 | return -1; 50 | } 51 | 52 | *ctx = spng_context; 53 | 54 | spng_set_crc_action(spng_context, SPNG_CRC_USE, SPNG_CRC_USE); 55 | const size_t chunk_limit = 1 << 20; 56 | spng_set_chunk_limits(spng_context, chunk_limit, chunk_limit); 57 | 58 | spng_set_png_file(spng_context, fin); 59 | 60 | int ret = spng_get_ihdr(spng_context, ihdr); 61 | if (ret) { 62 | *error_msg = spng_strerror(ret); 63 | return -1; 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | int main(int argc, const char *argv[]) { 70 | uint64_t width = 0, height = 0; 71 | void *buffer = NULL, *output_buffer = NULL; 72 | HYDEncoder *encoder = NULL; 73 | int ret = 1; 74 | FILE *fout = stdout, *fin = stdin; 75 | const char *error_msg = NULL; 76 | spng_ctx *spng_context = NULL; 77 | 78 | fprintf(stderr, "libhydrium version %s\n", HYDRIUM_VERSION_STRING); 79 | 80 | if (argc < 2) { 81 | print_usage(argv[0]); 82 | return 1; 83 | } 84 | 85 | int one_frame = 0; 86 | int pfm = -1; 87 | int linear = 0; 88 | int endianness = 0; 89 | long tilesize = 0; 90 | int argp = 0; 91 | const char *in_fname = NULL; 92 | const char *out_fname = NULL; 93 | int found_mm = 0; 94 | 95 | while (++argp < argc) { 96 | if (found_mm || strncmp(argv[argp], "--", 2)) { 97 | if (!in_fname) 98 | in_fname = argv[argp]; 99 | else if (!out_fname) 100 | out_fname = argv[argp]; 101 | else { 102 | fprintf(stderr, "Invalid trailing arg: %s\n", argv[argp]); 103 | fprintf(stderr, "Please run: %s --help\n", argv[0]); 104 | return 2; 105 | } 106 | } else if (!strcmp(argv[argp], "--help")) { 107 | print_usage(argv[0]); 108 | return 0; 109 | } else if (!argv[argp][2]) { 110 | found_mm = 1; 111 | } else if (!strcmp(argv[argp], "--one-frame")) { 112 | one_frame = 1; 113 | } else if (!strncmp(argv[argp], "--tile-size=", 12)) { 114 | errno = 0; 115 | tilesize = strtol(argv[argp] + 12, NULL, 10); 116 | if (errno) { 117 | fprintf(stderr, "Invalid integer: %s\n", argv[argp] + 12); 118 | fprintf(stderr, "Please run: %s --help\n", argv[0]); 119 | return 2; 120 | } 121 | if (tilesize < 0 || tilesize > 3) { 122 | fprintf(stderr, "Invalid tile size, must be 0-3: %s\n", argv[argp] + 12); 123 | fprintf(stderr, "Please run: %s --help\n", argv[0]); 124 | return 2; 125 | } 126 | } else if (!strcmp(argv[argp], "--pfm")) { 127 | pfm = 1; 128 | } else if (!strcmp(argv[argp], "--png")) { 129 | pfm = 0; 130 | } else if (!strcmp(argv[argp], "--linear")) { 131 | linear = 1; 132 | } 133 | } 134 | 135 | if (in_fname && pfm < 0) { 136 | size_t len = strlen(in_fname); 137 | if (len > 3) { 138 | pfm = !strncmp(in_fname + len - 4, ".pfm", 4); 139 | } else { 140 | pfm = 0; 141 | } 142 | } else if (pfm < 0) { 143 | pfm = 0; 144 | } 145 | 146 | if (in_fname && strcmp(in_fname, "-")) { 147 | fin = fopen(in_fname, "rb"); 148 | if (!fin) { 149 | fprintf(stderr, "%s: error opening file: %s\n", argv[0], in_fname); 150 | goto done; 151 | } 152 | #ifdef _WIN32 153 | } else { 154 | ret = _setmode(_fileno(fin), _O_BINARY); 155 | if (ret) 156 | goto done; 157 | #endif 158 | } 159 | 160 | struct spng_ihdr ihdr; 161 | 162 | if (!pfm) { 163 | ret = init_spng_stream(&spng_context, &error_msg, fin, &ihdr); 164 | if (ret < 0) 165 | goto done; 166 | width = ihdr.width; 167 | height = ihdr.height; 168 | } else { 169 | int c; 170 | char sig[3]; 171 | size_t r = fread(sig, 3, 1, fin); 172 | if (!r || memcmp(sig, pfm_sig, 3)) { 173 | error_msg = "not a color PFM file"; 174 | goto done; 175 | } 176 | while (1) { 177 | /* 178 | * we read this one char at a time 179 | * in order to prevent from overreading 180 | */ 181 | c = fgetc(fin); 182 | if (c >= '0' && c <= '9') 183 | width = width * 10 + (c - '0'); 184 | else if (c == ' ') 185 | break; 186 | else { 187 | error_msg = "invalid PFM width"; 188 | goto done; 189 | } 190 | if (width > (UINT64_C(1) << 30)) 191 | break; 192 | } 193 | while (1) { 194 | c = fgetc(fin); 195 | if (c >= '0' && c <= '9') 196 | height = height * 10 + (c - '0'); 197 | else if (c == '\n') 198 | break; 199 | else { 200 | error_msg = "invalid PFM height"; 201 | goto done; 202 | } 203 | if (height > (UINT64_C(1) << 30)) 204 | break; 205 | } 206 | c = fgetc(fin); 207 | if (c != '-') 208 | endianness = 1; 209 | else 210 | endianness = -1; 211 | int n = 0; 212 | while (1) { 213 | c = fgetc(fin); 214 | if (c == '\n') 215 | break; 216 | /* disallow >64 chars for endianness for sanity */ 217 | if (c < 0 || n++ > 64) { 218 | error_msg = "invalid PFM endianness"; 219 | goto done; 220 | } 221 | } 222 | } 223 | 224 | if (pfm) { 225 | const int i = 1; 226 | int little = *((char *)&i); 227 | int ne = (little && endianness < 0) || (!little && endianness > 0); 228 | endianness = ne ? 1 : -1; 229 | } 230 | 231 | if (width > (UINT64_C(1) << 30) || height > (UINT64_C(1) << 30) || width * height > (UINT64_C(1) << 40)) { 232 | fprintf(stderr, "%s: buffer too big\n", argv[0]); 233 | goto done; 234 | } 235 | 236 | enum spng_format sample_fmt = 0; 237 | ptrdiff_t buffer_stride; 238 | size_t decoded_image_buffer_size; 239 | if (!pfm) { 240 | sample_fmt = ihdr.bit_depth > 8 ? SPNG_FMT_RGBA16 : SPNG_FMT_RGB8; 241 | ret = spng_decoded_image_size(spng_context, sample_fmt, &decoded_image_buffer_size); 242 | if (ret) { 243 | fprintf(stderr, "%s: spng error: %s\n", argv[0], spng_strerror(ret)); 244 | goto done; 245 | } 246 | buffer_stride = decoded_image_buffer_size / height; 247 | } else { 248 | buffer_stride = 12 * width; 249 | decoded_image_buffer_size = buffer_stride * height; 250 | } 251 | 252 | HYDImageMetadata metadata; 253 | metadata.width = width; 254 | metadata.height = height; 255 | metadata.linear_light = linear; 256 | metadata.tile_size_shift_x = one_frame ? -1 : tilesize; 257 | metadata.tile_size_shift_y = one_frame ? -1 : tilesize; 258 | const uint32_t size_shift_x = metadata.tile_size_shift_x < 0 ? 3 : metadata.tile_size_shift_x; 259 | const uint32_t size_shift_y = metadata.tile_size_shift_y < 0 ? 3 : metadata.tile_size_shift_y; 260 | const uint32_t tile_size_x = 256 << size_shift_x; 261 | const uint32_t tile_size_y = 256 << size_shift_y; 262 | const uint32_t tile_width = (width + tile_size_x - 1) >> (8 + size_shift_x); 263 | const uint32_t tile_height = (height + tile_size_y - 1) >> (8 + size_shift_y); 264 | 265 | if (!pfm) { 266 | buffer = malloc(ihdr.interlace_method != SPNG_INTERLACE_NONE ? 267 | decoded_image_buffer_size : buffer_stride * tile_size_y); 268 | } else { 269 | buffer = malloc(buffer_stride * tile_size_y); 270 | } 271 | 272 | if (!buffer) { 273 | fprintf(stderr, "%s: not enough memory\n", argv[0]); 274 | goto done; 275 | } 276 | 277 | size_t output_bufsize = 1 << 20; 278 | output_buffer = malloc(output_bufsize); 279 | if (!output_buffer) { 280 | fprintf(stderr, "%s: not enough memory\n", argv[0]); 281 | goto done; 282 | } 283 | 284 | if (!pfm) { 285 | if (ihdr.interlace_method != SPNG_INTERLACE_NONE) 286 | ret = spng_decode_image(spng_context, buffer, decoded_image_buffer_size, sample_fmt, 0); 287 | else 288 | ret = spng_decode_image(spng_context, NULL, 0, sample_fmt, SPNG_DECODE_PROGRESSIVE); 289 | if (ret) { 290 | fprintf(stderr, "%s: spng error: %s\n", argv[0], spng_strerror(ret)); 291 | goto done; 292 | } 293 | } 294 | 295 | encoder = hyd_encoder_new(); 296 | if (!encoder) { 297 | fprintf(stderr, "%s: error allocating encoder\n", argv[0]); 298 | goto done; 299 | } 300 | 301 | if (out_fname && strcmp(out_fname, "-")) { 302 | fout = fopen(out_fname, "wb"); 303 | if (!fout) { 304 | fprintf(stderr, "%s: error opening file for writing: %s\n", argv[0], out_fname); 305 | goto done; 306 | } 307 | #ifdef _WIN32 308 | } else { 309 | ret = _setmode(_fileno(fout), _O_BINARY); 310 | if (ret) 311 | goto done; 312 | #endif 313 | } 314 | 315 | if (hyd_isatty(fout)) { 316 | fprintf(stderr, "%s: Not writing compressed data to a terminal.\n", argv[0]); 317 | print_usage(argv[0]); 318 | ret = 3; 319 | goto done; 320 | } 321 | 322 | ret = hyd_set_metadata(encoder, &metadata); 323 | if (ret < HYD_ERROR_START) 324 | goto done; 325 | 326 | ret = hyd_provide_output_buffer(encoder, output_buffer, output_bufsize); 327 | if (ret < HYD_ERROR_START) 328 | goto done; 329 | 330 | struct spng_row_info row_info = {0}; 331 | for (uint32_t yk = 0; yk < tile_height; yk++) { 332 | uint32_t y = pfm ? tile_height - yk - 1 : yk; 333 | uint32_t this_tile_height = tile_size_y; 334 | if (!pfm && ihdr.interlace_method == SPNG_INTERLACE_NONE) { 335 | size_t gy = 0; 336 | do { 337 | ret = spng_get_row_info(spng_context, &row_info); 338 | if (ret) 339 | break; 340 | ret = spng_decode_row(spng_context, buffer + gy * buffer_stride, buffer_stride); 341 | } while (!ret && ++gy < tile_size_y); 342 | 343 | if (ret && ret != SPNG_EOI) { 344 | fprintf(stderr, "%s: spng error: %s\n", argv[0], spng_strerror(ret)); 345 | goto done; 346 | } 347 | } else if (pfm) { 348 | if (!yk) 349 | this_tile_height = height - ((height - 1) / tile_size_y) * tile_size_y; 350 | for (size_t gy = 0; gy < this_tile_height; gy++) { 351 | void *row = buffer + gy * buffer_stride; 352 | size_t read = fread(row, buffer_stride, 1, fin); 353 | if (!read) { 354 | fprintf(stderr, "%s: incomplete pfm read\n", argv[0]); 355 | goto done; 356 | } 357 | if (endianness < 0) { 358 | uint32_t *irow = row; 359 | for (size_t gx = 0; gx < 3 * width; gx++) { 360 | const uint32_t n = irow[gx]; 361 | /* gcc generates a single bswap instruction here */ 362 | irow[gx] = ((n & UINT32_C(0xff000000)) >> 24) | ((n & UINT32_C(0x00ff0000)) >> 8) 363 | | ((n & UINT32_C(0x0000ff00)) << 8) | ((n & UINT32_C(0xff)) << 24); 364 | } 365 | } 366 | } 367 | } 368 | for (uint32_t x = 0; x < tile_width; x++) { 369 | if (!pfm && ihdr.bit_depth > 8) { 370 | const uint16_t *tile_buffer = ((const uint16_t *)buffer) + x * tile_size_x * 4; 371 | const void *const rgb[3] = {tile_buffer, tile_buffer + 1, tile_buffer + 2}; 372 | // We divide by 2 because spng_stride is in bytes, not in uint16_t units 373 | ret = hyd_send_tile(encoder, rgb, x, y, buffer_stride / 2, 4, -1, HYD_UINT16); 374 | } else if (!pfm) { 375 | const uint8_t *tile_buffer = ((const uint8_t *)buffer) + x * tile_size_x * 3; 376 | const void *const rgb[3] = {tile_buffer, tile_buffer + 1, tile_buffer + 2}; 377 | ret = hyd_send_tile(encoder, rgb, x, y, buffer_stride, 3, -1, HYD_UINT8); 378 | } else { 379 | /* pfm goes from bottom to top for some reason */ 380 | void *buffer_bottom = buffer + buffer_stride * (this_tile_height - 1); 381 | const float *tile_buffer = ((const float *)buffer_bottom) + x * tile_size_x * 3; 382 | const void *const rgb[3] = {tile_buffer, tile_buffer + 1, tile_buffer + 2}; 383 | ret = hyd_send_tile(encoder, rgb, x, y, -buffer_stride / 4, 3, y == 0 && x == tile_width - 1, 384 | HYD_FLOAT32); 385 | } 386 | if (ret < HYD_ERROR_START) 387 | goto done; 388 | do { 389 | ret = hyd_flush(encoder); 390 | size_t written; 391 | HYDStatusCode ret2 = hyd_release_output_buffer(encoder, &written); 392 | if (ret2 < HYD_ERROR_START) 393 | goto done; 394 | size_t fout_written = fwrite(output_buffer, written, 1, fout); 395 | if (written && !fout_written) 396 | goto done; 397 | ret2 = hyd_provide_output_buffer(encoder, output_buffer, output_bufsize); 398 | if (ret2 < HYD_ERROR_START) 399 | goto done; 400 | } while (ret == HYD_NEED_MORE_OUTPUT); 401 | if (ret != HYD_OK) 402 | goto done; 403 | } 404 | } 405 | 406 | done: 407 | if (fout) 408 | fclose(fout); 409 | if (fin) 410 | fclose(fin); 411 | if (spng_context) 412 | spng_ctx_free(spng_context); 413 | if (encoder) { 414 | error_msg = hyd_error_message_get(encoder); 415 | hyd_encoder_destroy(encoder); 416 | } 417 | free(buffer); 418 | free(output_buffer); 419 | if (ret < HYD_ERROR_START) 420 | fprintf(stderr, "Hydrium error occurred. Error code: %d\n", ret); 421 | if (error_msg && *error_msg) 422 | fprintf(stderr, "Error message: %s\n", error_msg); 423 | 424 | return ret; 425 | } 426 | -------------------------------------------------------------------------------- /src/include/libhydrium/libhydrium.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libhydrium/libhydrium.h 3 | * 4 | * This is the main libhydrium API entry point. 5 | */ 6 | 7 | #ifndef HYDRIUM_H_ 8 | #define HYDRIUM_H_ 9 | 10 | #include 11 | #include 12 | 13 | /* 14 | * Major version, following semantic versioning. 15 | * If positive, dictates the API and ABI. 16 | */ 17 | #define HYDRIUM_VERSION_MAJOR 0 18 | /* 19 | * Minor version, following semantic versioning. 20 | */ 21 | #define HYDRIUM_VERSION_MINOR 5 22 | /* 23 | * Point release, following semantic versioning. 24 | */ 25 | #define HYDRIUM_VERSION_POINT 0 26 | 27 | /* 28 | * Compute the numeric version. Used to compare version numbers directly 29 | */ 30 | #define HYDRIUM_COMPUTE_VERSION(ma, mi, po) (UINT64_C(0x1000000000) \ 31 | | ((uint64_t)(ma) << 24) \ 32 | | ((uint64_t)(mi) << 12) \ 33 | | ((uint64_t)(po))) 34 | 35 | /* 36 | * The format of the version integer is: 37 | * 0x1XXXYYYZZZ where XXX is the major version, YYY is the minor version, 38 | * and ZZZ is the point release. 39 | */ 40 | #define HYDRIUM_VERSION_INT HYDRIUM_COMPUTE_VERSION(\ 41 | HYDRIUM_VERSION_MAJOR, \ 42 | HYDRIUM_VERSION_MINOR, \ 43 | HYDRIUM_VERSION_POINT) 44 | 45 | #define HYD_STRINGIFY(n) HYD_STRINGIFY0(n) 46 | #define HYD_STRINGIFY0(n) #n 47 | 48 | #define HYDRIUM_VERSION_STRING \ 49 | HYD_STRINGIFY(HYDRIUM_VERSION_MAJOR) "." \ 50 | HYD_STRINGIFY(HYDRIUM_VERSION_MINOR) "." \ 51 | HYD_STRINGIFY(HYDRIUM_VERSION_POINT) 52 | 53 | #ifdef _WIN32 54 | #ifdef HYDRIUM_INTERNAL_BUILD 55 | #define HYDRIUM_EXPORT __declspec(dllexport) 56 | #else 57 | #define HYDRIUM_EXPORT __declspec(dllimport) 58 | #endif 59 | #else 60 | #if defined(__GNUC__) || defined(__CLANG__) 61 | #define HYDRIUM_EXPORT __attribute__((visibility ("default"))) 62 | #else 63 | #define HYDRIUM_EXPORT 64 | #endif /* __GNUC__ || __clang__ */ 65 | #endif 66 | 67 | typedef enum HYDStatusCode { 68 | /** 69 | * Everything is OK. 70 | */ 71 | HYD_OK = 0, 72 | /** 73 | * Used internally only, and never returned by the API. 74 | */ 75 | HYD_DEFAULT = -1, 76 | /** 77 | * Another output buffer is needed. 78 | */ 79 | HYD_NEED_MORE_OUTPUT = -2, 80 | /** 81 | * More input must be provided. 82 | */ 83 | HYD_NEED_MORE_INPUT = -3, 84 | /** 85 | * Every proper error code is less than HYD_ERROR_START, which is negative. 86 | * This is not an actual error and it is never returned. 87 | */ 88 | HYD_ERROR_START = -10, 89 | /** 90 | * A heap allocation failed due to insufficient memory remaining. 91 | */ 92 | HYD_NOMEM = -13, 93 | /** 94 | * Incorrect API use detected. 95 | */ 96 | HYD_API_ERROR = -14, 97 | /** 98 | * An internal error occurred. If this is returned, something went wrong. 99 | */ 100 | HYD_INTERNAL_ERROR = -15, 101 | } HYDStatusCode; 102 | 103 | typedef enum HYDSampleFormat { 104 | HYD_UINT8, 105 | HYD_UINT16, 106 | HYD_FLOAT32, 107 | } HYDSampleFormat; 108 | 109 | typedef struct HYDImageMetadata { 110 | /** 111 | * The width of the image, in pixels. 112 | */ 113 | size_t width; 114 | 115 | /** 116 | * The height of the image, in pixels. 117 | */ 118 | size_t height; 119 | 120 | /** 121 | * A flag indicating whether the input data is in Linear Light. If true, the input 122 | * is treated as linear-light. If false, the input is treated as sRGB. 123 | * In both cases the input is assumed to have BT.709 primaries (same as sRGB), 124 | * and a D65 white point. 125 | */ 126 | int linear_light; 127 | 128 | /** 129 | * Indicates the horizontal size of a tile. Valid values are 130 | * 0, 1, 2, and 3, corresponding to 256, 512, 1024, and 2048 131 | * pixels wide. 132 | * 133 | * Tiles may be larger than the image width, in which case only 134 | * one tile will exist in the horizontal direction. 135 | * 136 | * A special value of -1 may be passed, which tells libhydrium to 137 | * use one Frame for the entire image. This mode uses more memory, 138 | * but it decodes faster with libjxl. 139 | */ 140 | int tile_size_shift_x; 141 | 142 | /** 143 | * Indicates the vertical size of a tile. Valid values are 144 | * 0, 1, 2, and 3, corresponding to 256, 512, 1024, and 2048 145 | * pixels high. 146 | * 147 | * Tiles may be larger than the image height, in which case only 148 | * one tile will exist in the vertical direction. 149 | * 150 | * A special value of -1 may be passed, which tells libhydrium to 151 | * use one Frame for the entire image. This mode uses more memory, 152 | * but it decodes faster with libjxl. 153 | */ 154 | int tile_size_shift_y; 155 | } HYDImageMetadata; 156 | 157 | /* opaque structure */ 158 | typedef struct HYDEncoder HYDEncoder; 159 | 160 | /** 161 | * @brief Allocate and return a fresh HYDEncoder struct. 162 | * 163 | * @return A new (HYDEncoder *) object upon success, NULL if the allocation fails. 164 | */ 165 | HYDRIUM_EXPORT HYDEncoder *hyd_encoder_new(void); 166 | 167 | /** 168 | * @brief Deallocate and free all resources associated with the given encoder. 169 | * 170 | * @param encoder A HYDEncoder struct. 171 | * @return HYD_OK upon success, or a negative error code upon failure. 172 | */ 173 | HYDRIUM_EXPORT HYDStatusCode hyd_encoder_destroy(HYDEncoder *encoder); 174 | 175 | /** 176 | * @brief Populate the given encoder with the image metadata set to encode. 177 | * This must be called before hyd_send_tile or its variants. 178 | * 179 | * @param encoder A HYDEncoder struct. 180 | * @param metadata A struct containing various image metadata parameters. 181 | * @return HYD_OK upon success, a negative error code upon failure. 182 | */ 183 | HYDRIUM_EXPORT HYDStatusCode hyd_set_metadata(HYDEncoder *encoder, const HYDImageMetadata *metadata); 184 | 185 | /** 186 | * @brief Provide an output buffer into which the encoded JPEG XL image will be written. 187 | * 188 | * @param encoder A HYDEncoder struct. 189 | * @param buffer A buffer of bytes that will contain (a part of) the encoded image data. 190 | * @param buffer_len The length of the buffer, in bytes. 191 | * @return HYD_OK upon success, a negative error code upon failure. 192 | */ 193 | HYDRIUM_EXPORT HYDStatusCode hyd_provide_output_buffer(HYDEncoder *encoder, uint8_t *buffer, size_t buffer_len); 194 | 195 | /** 196 | * @brief Provide a buffer of RGB pixel data to the hydrium encoder for it to encode. 197 | * 198 | * By default, hydrium encodes one tile at a time, and no tile references any other tile. A tile is 256x256, 199 | * unless tile_size_shift_x and/or tile_size_shift_y are set to something positive. In that case, the size of a 200 | * tile will be WxH, where W is (256 << tile_size_shift_x) and H is (256 << tile_size_shift_y). 201 | * 202 | * This function accepts an array of three buffers of pixel data, although they may overlap. 203 | * 204 | * The X and Y coordinates of the tile passed refer to the coordinates in numbers of tiles, 205 | * not in numbers of pixels, and starts from the upper left and proceeds in raster order. 206 | * For example, the tile immediately to the right of the upper-left tile has x=1 and y=0. 207 | * 208 | * The buffer passed treats buffer[0] as the red channel, buffer[1] as the green channel, 209 | * and buffer[2] as the blue channel. In the case where these buffers are all distinct, you probably 210 | * wish to set pixel_stride to 1, as each sample will be next to the previous sample. row_stride 211 | * is the pointer difference between two rows of a buffer. 212 | * 213 | * If you wish to pass packed data instead of planar data, set buffer[0] to the first red sample, 214 | * set buffer[1] to the first green sample, and set buffer[2] to the first blue sample. The distance 215 | * between adjacent red samples will be 3 in this case, so set pixel_stride to 3, not to 1. Row-stride 216 | * is the pointer difference between two rows of this buffer, as before, so buffer[0] + row_stride will 217 | * point to the first red sample in the second row of the tile. 218 | * 219 | * Note that the stride arguments are in units of samples, not bytes. Do not double them for 16-bit input, as 220 | * C already handles that when you add pointers. 221 | * 222 | * If the encoded tile does not fit in the remaining provided output buffer, HYD_NEED_MORE_OUTPUT is returned. 223 | * If so, you must call hyd_release_output_buffer to regain ownership of the output buffer. Do whatever with the 224 | * data (fwrite, send to a network stream, whatever), and then you must provide another output buffer with 225 | * hyd_provide_output_buffer. After you provide another output buffer, do not send the same tile again, instead 226 | * call hyd_flush to flush the remaining encoded tile to the output buffer. 227 | * 228 | * Tiles are always multiples of 256x256, although images are not always a multiple of 256 pixels in each direction. 229 | * If so, the rightmost column and bottom-most row of tiles will be smaller. Make sure you set row_stride correctly 230 | * for the right-most column, as hydrium will not automatically assume it is smaller than the one provided. Because 231 | * the image width and height were provided with hyd_set_metadata, hydrium will know how big these tiles should be 232 | * and it will not overrun the buffers. 233 | * 234 | * If the encoded tile is fully written to the output buffer, then HYD_OK will be returned, and it 235 | * is time to send another tile. Tiles may be sent in any order, although libhydrium will assume that the 236 | * lower-right tile is the last tile. Passing 0 or 1 to is_last will explicitly tell libhydrium if the sent tile is 237 | * the last one - otherwise, pass a negative value to use the above default behavior. Sending another tile 238 | * after the last one is undefined behavior. 239 | * 240 | * Any tile except the last one may be left unsent, and these gaps will be populated by zeroes. 241 | * 242 | * If the last tile is sent and the output buffer is not full, HYD_OK is returned. Any return value other than 243 | * HYD_NEED_MORE_OUTPUT or HYD_OK is an error. 244 | * 245 | * The sample format may vary from tile to tile. Internally, libhydrium will scale uint8_t samples, assumed to be 246 | * full-range between 0 and 255, to float values between 0.0 and 1.0. uint16_t samples will be scaled from the full 247 | * range of 0 to 65535, to float values between 0.0 and 1.0. To pass out-of-gamut colors you must pass float samples 248 | * less than 0.0 or more than 1.0, as float samples when passed are not rescaled. However, it is undefined behavior 249 | * to pass infinite or NaN float samples. 250 | * 251 | * @param encoder A HYDEncoder struct. 252 | * @param buffer An array of three buffers of pixel data. 253 | * @param tile_x The X-coordinate, in tiles, of the encoded tile. 254 | * @param tile_y The Y-coordinate, in tiles, of the encoded tile. 255 | * @param row_stride The line size of the pixel buffer. 256 | * @param pixel_stride The inter-pixel stride of the buffer. 257 | * @param is_last A flag indicating whether the sent tile is the last one. 258 | * @param sample_fmt The sample format of the provided buffer. 259 | */ 260 | HYDRIUM_EXPORT HYDStatusCode hyd_send_tile(HYDEncoder *encoder, const void *const buffer[3], 261 | uint32_t tile_x, uint32_t tile_y, ptrdiff_t row_stride, 262 | ptrdiff_t pixel_stride, int is_last, HYDSampleFormat sample_fmt); 263 | 264 | /** 265 | * @brief Release the output buffer that was previously provided by hyd_provide_output_buffer. 266 | * 267 | * The value of *written will be populated by the amount of data actually written to the provided 268 | * output buffer, which may be smaller than its size. Once this is called, another buffer must 269 | * be provided with hyd_provide_output_buffer before any more data can be written. 270 | * 271 | * @param encoder A HYDEncoder struct. 272 | * @param written Populated by the amount of data actually written to the buffer. 273 | * @return HYD_OK upon success, a negative status code upon failure. 274 | */ 275 | HYDRIUM_EXPORT HYDStatusCode hyd_release_output_buffer(HYDEncoder *encoder, size_t *written); 276 | 277 | /** 278 | * @brief Flush the encoded data to the provided buffer. 279 | * 280 | * After swapping out a buffer with hyd_release_output_buffer and then again calling 281 | * hyd_provide_output_buffer, the remaining encoded data in the tile must be drained to the new buffer 282 | * by calling hyd_flush. Tiles will only be sent once, so this function is used to flush the remaining 283 | * output to the newly provided buffer. 284 | * 285 | * @param encoder A HYDEncoder struct. 286 | * @return HYD_OK upon success, a negative status code upon failure. 287 | */ 288 | HYDRIUM_EXPORT HYDStatusCode hyd_flush(HYDEncoder *encoder); 289 | 290 | /** 291 | * @brief Returns a string description of the last error that occurred. 292 | * 293 | * @param encoder A HYDEncoder struct. 294 | */ 295 | HYDRIUM_EXPORT const char *hyd_error_message_get(HYDEncoder *encoder); 296 | 297 | #endif /* HYDRIUM_H_ */ 298 | -------------------------------------------------------------------------------- /src/libhydrium/bitwriter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Bit Writer implementation 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "bitwriter.h" 10 | #include "internal.h" 11 | 12 | HYDStatusCode hyd_init_bit_writer(HYDBitWriter *bw, uint8_t *buffer, size_t buffer_len, 13 | uint64_t cache, int cache_bits) { 14 | bw->buffer = buffer; 15 | bw->buffer_len = buffer_len; 16 | bw->buffer_pos = 0; 17 | bw->cache = cache; 18 | bw->cache_bits = cache_bits; 19 | bw->overflow_state = HYD_OK; 20 | memset(bw->overflow, 0, sizeof(bw->overflow)); 21 | bw->overflow_pos = 0; 22 | return HYD_OK; 23 | } 24 | 25 | static HYDStatusCode drain_cache(HYDBitWriter *bw) { 26 | while (bw->cache_bits >= 8) { 27 | uint8_t *buf = bw->buffer_pos >= bw->buffer_len ? 28 | bw->overflow + bw->overflow_pos++ : 29 | bw->buffer + bw->buffer_pos++; 30 | *buf = bw->cache & 0xFF; 31 | bw->cache >>= 8; 32 | bw->cache_bits -= 8; 33 | } 34 | 35 | if (bw->overflow_pos) { 36 | if (bw->overflow_pos > sizeof(bw->overflow)) 37 | return HYD_INTERNAL_ERROR; 38 | if (bw->realloc_func) { 39 | bw->overflow_state = bw->realloc_func(&bw->buffer, &bw->buffer_len); 40 | if (bw->overflow_state < HYD_ERROR_START) 41 | return bw->overflow_state; 42 | memcpy(bw->buffer + bw->buffer_pos, bw->overflow, bw->overflow_pos); 43 | bw->buffer_pos += bw->overflow_pos; 44 | bw->overflow_pos = 0; 45 | } else { 46 | bw->overflow_state = HYD_NEED_MORE_OUTPUT; 47 | } 48 | } 49 | 50 | return bw->overflow_state; 51 | } 52 | 53 | HYDStatusCode hyd_write(HYDBitWriter *bw, uint64_t value, int bits) { 54 | if (bits <= 0) 55 | return bw->overflow_state; 56 | if (bits > 56) 57 | return HYD_API_ERROR; 58 | if (bits <= 64 - bw->cache_bits) { 59 | bw->cache |= (value & ~(~UINT64_C(0) << bits)) << bw->cache_bits; 60 | bw->cache_bits += bits; 61 | return bw->overflow_state; 62 | } 63 | HYDStatusCode ret = drain_cache(bw); 64 | if (ret < HYD_ERROR_START) 65 | return ret; 66 | return hyd_write(bw, value, bits); 67 | } 68 | 69 | HYDStatusCode hyd_write_zero_pad(HYDBitWriter *bw) { 70 | return hyd_write(bw, 0, 7 - ((bw->cache_bits + 7) & 0x7)); 71 | } 72 | 73 | HYDStatusCode hyd_write_bool(HYDBitWriter *bw, int flag) { 74 | return hyd_write(bw, !!flag, 1); 75 | } 76 | 77 | HYDStatusCode hyd_write_u32(HYDBitWriter *bw, const U32Table *table, uint32_t value) { 78 | for (int i = 0; i < 4; i++) { 79 | const uint64_t max = ~(~UINT64_C(0) << table->upos[i]); 80 | const uint64_t vmc = value - table->cpos[i]; 81 | if (vmc <= max) 82 | return hyd_write(bw, (vmc << 2) | i, table->upos[i] + 2); 83 | } 84 | return HYD_API_ERROR; 85 | } 86 | 87 | HYDStatusCode hyd_bitwriter_flush(HYDBitWriter *bw) { 88 | HYDStatusCode ret; 89 | ret = hyd_write_zero_pad(bw); 90 | if (ret < HYD_ERROR_START) 91 | return ret; 92 | return drain_cache(bw); 93 | } 94 | 95 | HYDStatusCode hyd_write_u64(HYDBitWriter *bw, uint64_t value) { 96 | if (!value) 97 | return hyd_write(bw, 0, 2); 98 | if (value < 17) 99 | return hyd_write(bw, ((value - 1) << 2) | 1, 4 + 2); 100 | if (value < 273) 101 | return hyd_write(bw, ((value - 17) << 2) | 2, 8 + 2); 102 | hyd_write(bw, ((value & 0xFFF) << 2) | 3, 2 + 12); 103 | int shift = 12; 104 | while (1) { 105 | uint64_t svalue = value >> shift; 106 | if (!svalue) 107 | return hyd_write(bw, 0, 1); 108 | if (shift == 60) { 109 | return hyd_write(bw, ((svalue & 0xF) << 1) | 1, 1 + 4); 110 | } else { 111 | hyd_write(bw, ((svalue & 0xFF) << 1) | 1, 1 + 8); 112 | shift += 8; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/libhydrium/bitwriter.h: -------------------------------------------------------------------------------- 1 | #ifndef HYDRIUM_BITWRITER_H_ 2 | #define HYDRIUM_BITWRITER_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "libhydrium/libhydrium.h" 8 | 9 | typedef struct HYDBitWriter { 10 | uint8_t *buffer; 11 | size_t buffer_pos; 12 | size_t buffer_len; 13 | uint64_t cache; 14 | int cache_bits; 15 | uint8_t overflow[32]; 16 | size_t overflow_pos; 17 | int overflow_state; 18 | HYDStatusCode (*realloc_func)(uint8_t **buffer, size_t *buffer_len); 19 | } HYDBitWriter; 20 | 21 | typedef struct U32Table { 22 | const uint32_t cpos[4]; 23 | const uint32_t upos[4]; 24 | } U32Table; 25 | 26 | HYDStatusCode hyd_init_bit_writer(HYDBitWriter *bw, uint8_t *buffer, size_t buffer_len, uint64_t cache, int cache_bits); 27 | HYDStatusCode hyd_write(HYDBitWriter *bw, uint64_t value, int bits); 28 | 29 | HYDStatusCode hyd_write_zero_pad(HYDBitWriter *bw); 30 | HYDStatusCode hyd_write_u32(HYDBitWriter *bw, const U32Table *table, uint32_t value); 31 | HYDStatusCode hyd_write_u64(HYDBitWriter *bw, uint64_t value); 32 | HYDStatusCode hyd_write_bool(HYDBitWriter *bw, int flag); 33 | HYDStatusCode hyd_bitwriter_flush(HYDBitWriter *bw); 34 | 35 | #endif /* HYDRIUM_BITWRITER_H_ */ 36 | -------------------------------------------------------------------------------- /src/libhydrium/cluster-map.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Cluster Map for HF Coefficients 3 | */ 4 | #include 5 | 6 | const uint8_t hf_cluster_map[7425] = { 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, 8 | 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, 9 | 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, 10 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11 | 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, 12 | 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, 13 | 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, 14 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15 | 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, 16 | 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, 17 | 7, 7, 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, 18 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 19 | 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, 20 | 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, 21 | 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 22 | 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, 23 | 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, 24 | 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, 25 | 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, 26 | 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, 27 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 28 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 29 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 30 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 31 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 32 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 33 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 34 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 35 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 36 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 37 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 38 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 39 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 40 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 41 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 42 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 43 | 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 44 | 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 15, 30, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 45 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 46 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 47 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 48 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 49 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 50 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 51 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 52 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 53 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 54 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 55 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 56 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 57 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 58 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 59 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 60 | 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 61 | 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 16, 31, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 62 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 63 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 64 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 65 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 66 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 67 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 68 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 69 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 70 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 71 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 72 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 73 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 74 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 75 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 76 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 77 | 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 78 | 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 17, 32, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 79 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 80 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 81 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 82 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 83 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 84 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 85 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 86 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 87 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 88 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 89 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 90 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 91 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 92 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 93 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 94 | 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 95 | 33, 18, 33, 18, 33, 18, 33, 18, 33, 18, 33, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 96 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 97 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 98 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 99 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 100 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 101 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 102 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 103 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 104 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 105 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 106 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 107 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 108 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 109 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 110 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 111 | 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 112 | 19, 34, 19, 34, 19, 34, 19, 34, 19, 34, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 113 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 114 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 115 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 116 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 117 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 118 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 119 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 120 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 121 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 122 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 123 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 124 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 125 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 126 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 127 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 128 | 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 35, 20, 129 | 35, 20, 35, 20, 35, 20, 35, 20, 35, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 130 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 131 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 132 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 133 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 134 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 135 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 136 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 137 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 138 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 139 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 140 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 141 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 142 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 143 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 144 | 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 145 | 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 21, 36, 146 | 21, 36, 21, 36, 21, 36, 21, 36, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 147 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 148 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 149 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 150 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 151 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 152 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 153 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 154 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 155 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 156 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 157 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 158 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 159 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 160 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 161 | 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 162 | 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 37, 22, 163 | 37, 22, 37, 22, 37, 22, 37, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 164 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 165 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 166 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 167 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 168 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 169 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 170 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 171 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 172 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 173 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 174 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 175 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 176 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 177 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 178 | 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 179 | 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 23, 38, 180 | 23, 38, 23, 38, 23, 38, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 181 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 182 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 183 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 184 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 185 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 186 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 187 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 188 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 189 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 190 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 191 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 192 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 193 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 194 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 195 | 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 196 | 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 39, 24, 197 | 39, 24, 39, 24, 39, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 198 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 199 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 200 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 201 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 202 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 203 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 204 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 205 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 206 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 207 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 208 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 209 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 210 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 211 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 212 | 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 213 | 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 25, 40, 214 | 25, 40, 25, 40, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 215 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 216 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 217 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 218 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 219 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 220 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 221 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 222 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 223 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 224 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 225 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 226 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 227 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 228 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 229 | 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 230 | 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 41, 26, 231 | 41, 26, 41, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 232 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 233 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 234 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 235 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 236 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 237 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 238 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 239 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 240 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 241 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 242 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 243 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 244 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 245 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 246 | 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 247 | 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 27, 42, 248 | 27, 42, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 249 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 250 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 251 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 252 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 253 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 254 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 255 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 256 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 257 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 258 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 259 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 260 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 261 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 262 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 263 | 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 264 | 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 43, 28, 265 | 43, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 266 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 267 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 268 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 269 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 270 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 271 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 272 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 273 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 274 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 275 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 276 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 277 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 278 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 279 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 280 | 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 281 | 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 29, 44, 282 | }; 283 | -------------------------------------------------------------------------------- /src/libhydrium/encoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Base encoder implementation 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | #include "bitwriter.h" 9 | #include "encoder.h" 10 | #include "entropy.h" 11 | #include "internal.h" 12 | #include "math-functions.h" 13 | #include "memory.h" 14 | 15 | typedef struct IntPos { 16 | uint8_t x, y; 17 | } IntPos; 18 | 19 | static const uint8_t level10_header[49] = { 20 | 0x00, 0x00, 0x00, 0x0c, 'J', 'X', 'L', ' ', 21 | 0x0d, 0x0a, 0x87, 0x0a, 0x00, 0x00, 0x00, 0x14, 22 | 'f', 't', 'y', 'p', 'j', 'x', 'l', ' ', 23 | 0x00, 0x00, 0x00, 0x00, 'j', 'x', 'l', ' ', 24 | 0x00, 0x00, 0x00, 0x09, 'j', 'x', 'l', 'l', 0x0a, 25 | 0x00, 0x00, 0x00, 0x00, 'j', 'x', 'l', 'c', 26 | }; 27 | 28 | static const float cosine_lut[7][8] = { 29 | {0.17338, 0.146984, 0.0982119, 0.0344874, -0.0344874, -0.0982119, -0.146984, -0.17338}, 30 | {0.16332, 0.0676495, -0.0676495, -0.16332, -0.16332, -0.0676495, 0.0676495, 0.16332}, 31 | {0.146984, -0.0344874, -0.17338, -0.0982119, 0.0982119, 0.17338, 0.0344874, -0.146984}, 32 | {0.125, -0.125, -0.125, 0.125, 0.125, -0.125, -0.125, 0.125}, 33 | {0.0982119, -0.17338, 0.0344874, 0.146984, -0.146984, -0.0344874, 0.17338, -0.0982119}, 34 | {0.0676495, -0.16332, 0.16332, -0.0676495, -0.0676495, 0.16332, -0.16332, 0.0676495}, 35 | {0.0344874, -0.0982119, 0.146984, -0.17338, 0.17338, -0.146984, 0.0982119, -0.0344874}, 36 | }; 37 | 38 | static const IntPos natural_order[64] = { 39 | {0, 0}, {1, 0}, {0, 1}, {0, 2}, {1, 1}, {2, 0}, {3, 0}, {2, 1}, 40 | {1, 2}, {0, 3}, {0, 4}, {1, 3}, {2, 2}, {3, 1}, {4, 0}, {5, 0}, 41 | {4, 1}, {3, 2}, {2, 3}, {1, 4}, {0, 5}, {0, 6}, {1, 5}, {2, 4}, 42 | {3, 3}, {4, 2}, {5, 1}, {6, 0}, {7, 0}, {6, 1}, {5, 2}, {4, 3}, 43 | {3, 4}, {2, 5}, {1, 6}, {0, 7}, {1, 7}, {2, 6}, {3, 5}, {4, 4}, 44 | {5, 3}, {6, 2}, {7, 1}, {7, 2}, {6, 3}, {5, 4}, {4, 5}, {3, 6}, 45 | {2, 7}, {3, 7}, {4, 6}, {5, 5}, {6, 4}, {7, 3}, {7, 4}, {6, 5}, 46 | {5, 6}, {4, 7}, {5, 7}, {6, 6}, {7, 5}, {7, 6}, {6, 7}, {7, 7}, 47 | }; 48 | 49 | static const size_t coeff_freq_context[64] = { 50 | 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 51 | 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 52 | 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 53 | 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 54 | }; 55 | 56 | static const size_t coeff_num_non_zero_context[64] = { 57 | 0, 0, 31, 62, 62, 93, 93, 93, 93, 123, 123, 123, 123, 152, 58 | 152, 152, 152, 152, 152, 152, 152, 180, 180, 180, 180, 180, 180, 180, 59 | 180, 180, 180, 180, 180, 206, 206, 206, 206, 206, 206, 206, 206, 206, 60 | 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 61 | 206, 206, 206, 206, 206, 206, 206, 206, 62 | }; 63 | 64 | static const size_t hf_block_cluster_map[39] = { 65 | 0, 1, 2, 2, 3, 3, 4, 5, 6, 6, 6, 6, 6, 66 | 7, 8, 9, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 67 | 7, 8, 9, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 68 | }; 69 | 70 | static const int32_t hf_quant_weights[3][64] = { 71 | { 72 | 1969, 1969, 1969, 1962, 1969, 1962, 1655, 1885, 1885, 1655, 1397, 1610, 1704, 1610, 1397, 1178, 73 | 1368, 1494, 1494, 1368, 1178, 994, 1159, 1289, 1340, 1289, 1159, 994, 839, 980, 1104, 1178, 74 | 1178, 1104, 980, 839, 829, 941, 1023, 1054, 1023, 941, 829, 800, 881, 928, 928, 881, 75 | 800, 755, 809, 829, 809, 755, 663, 731, 731, 663, 491, 524, 491, 349, 349, 239, 76 | }, 77 | { 78 | 280, 280, 280, 279, 280, 279, 245, 271, 271, 245, 214, 239, 250, 239, 214, 188, 79 | 211, 226, 226, 211, 188, 164, 185, 201, 207, 201, 185, 164, 144, 163, 178, 188, 80 | 188, 178, 163, 144, 143, 157, 168, 172, 168, 157, 143, 139, 150, 156, 156, 150, 81 | 139, 133, 140, 143, 140, 133, 125, 129, 129, 125, 116, 118, 116, 107, 107, 98, 82 | }, 83 | { 84 | 256, 147, 147, 85, 117, 85, 60, 78, 78, 60, 43, 56, 63, 56, 43, 43, 85 | 43, 48, 48, 43, 43, 42, 43, 43, 43, 43, 43, 42, 29, 41, 43, 43, 86 | 43, 43, 41, 29, 29, 37, 43, 43, 43, 37, 29, 27, 33, 36, 36, 33, 87 | 27, 24, 27, 29, 27, 24, 20, 22, 22, 20, 15, 16, 15, 10, 10, 7, 88 | }, 89 | }; 90 | 91 | static const uint16_t hf_mult = 5; 92 | static const uint64_t zero64 = 0; 93 | static const void *const zerobuf = &zero64; 94 | static const U32Table size_header_u32 = { 95 | .cpos = {1, 1, 1, 1}, 96 | .upos = {9, 13, 18, 30}, 97 | }; 98 | static const U32Table frame_size_u32 = { 99 | .cpos = {0, 256, 2304, 18688}, 100 | .upos = {8, 11, 14, 30}, 101 | }; 102 | static const U32Table global_scale_table = { 103 | .cpos = {1, 2049, 4097, 8193}, 104 | .upos = {11, 11, 12, 16}, 105 | }; 106 | static const U32Table quant_lf_table = { 107 | .cpos = {16, 1, 1, 1}, 108 | .upos = {0, 5, 8, 16}, 109 | }; 110 | static const uint32_t lf_ma_tree[][2] = { 111 | {1, 0}, {2, 5}, {3, 0}, {4, 0}, {5, 0}, 112 | }; 113 | static const U32Table toc_table = { 114 | .cpos = {0, 1024, 17408, 4211712}, 115 | .upos = {10, 14, 22, 30}, 116 | }; 117 | 118 | extern const uint8_t hf_cluster_map[7425]; 119 | 120 | static HYDStatusCode write_header(HYDEncoder *encoder) { 121 | 122 | HYDBitWriter *bw = &encoder->writer; 123 | if (bw->overflow_state) 124 | return bw->overflow_state; 125 | 126 | if (encoder->level10) { 127 | /* skip the cache and copy directly in, as this is always the head of the file */ 128 | memcpy(bw->buffer + bw->buffer_pos, level10_header, sizeof(level10_header)); 129 | bw->buffer_pos += sizeof(level10_header); 130 | } 131 | 132 | /* signature = 0xFF0A:16 and div8 = 0:1 */ 133 | hyd_write(bw, 0x0AFF, 17); 134 | hyd_write_u32(bw, &size_header_u32, encoder->metadata.height); 135 | hyd_write(bw, 0, 3); 136 | hyd_write_u32(bw, &size_header_u32, encoder->metadata.width); 137 | 138 | /* all_default:1, default_m:1 */ 139 | hyd_write(bw, 0x3, 2); 140 | 141 | encoder->wrote_header = 1; 142 | return bw->overflow_state; 143 | } 144 | 145 | static void calculate_toc_perm(HYDEncoder *encoder, size_t toc_size, size_t *toc, size_t frame_gx) { 146 | toc[0] = 0; // LFGlobal 147 | if (toc_size == 1) { 148 | toc[1] = 0; 149 | return; 150 | } 151 | size_t idx = 1; 152 | for (size_t sent_lfid = 0; sent_lfid < encoder->lfg_per_frame; sent_lfid++) { 153 | size_t raster_lfid = encoder->lfg_perm ? encoder->lfg_perm[sent_lfid] : 0; 154 | toc[idx++] = 1 + raster_lfid; // LFGroup 155 | } 156 | for (size_t sent_lfid = 0; sent_lfid < encoder->lfg_per_frame; sent_lfid++) { 157 | if (sent_lfid == 0) 158 | toc[idx++] = 1 + encoder->lfg_per_frame; // HFGlobal 159 | size_t raster_lfid = encoder->lfg_perm ? encoder->lfg_perm[sent_lfid] : 0; 160 | const HYDLFGroup *lf_group = &encoder->lfg[raster_lfid]; 161 | const size_t gcountx = (lf_group->width + 255) >> 8; 162 | const size_t gcounty = (lf_group->height + 255) >> 8; 163 | const size_t gcount = gcountx * gcounty; 164 | for (size_t g = 0; g < gcount; g++) { 165 | size_t gy = (encoder->one_frame ? (lf_group->y << 3) : 0) + (g / gcountx); 166 | size_t gx = (encoder->one_frame ? (lf_group->x << 3) : 0) + (g % gcountx); 167 | toc[idx++] = 2 + encoder->lfg_per_frame + gy * frame_gx + gx; 168 | } 169 | } 170 | for (size_t j = 0; j < toc_size; j++) 171 | toc[toc_size + toc[j]] = j; 172 | } 173 | 174 | static HYDStatusCode get_lehmer_sequence(HYDEncoder *encoder, size_t *toc_size, size_t **lehmer_p, size_t lehmer_init) { 175 | HYDStatusCode ret = HYD_OK; 176 | size_t toc_perm_array[64]; 177 | size_t *toc_perm = toc_perm_array; 178 | int32_t temp_array[64]; 179 | int32_t *temp = temp_array; 180 | const size_t frame_h = encoder->one_frame ? encoder->metadata.height : encoder->lfg->height; 181 | const size_t frame_w = encoder->one_frame ? encoder->metadata.width : encoder->lfg->width; 182 | const size_t frame_groups_y = (frame_h + 255) >> 8; 183 | const size_t frame_groups_x = (frame_w + 255) >> 8; 184 | const size_t num_frame_groups = frame_groups_x * frame_groups_y; 185 | *toc_size = num_frame_groups > 1 ? 2 + num_frame_groups + encoder->lfg_per_frame : 1; 186 | if (*toc_size <= 1) 187 | return HYD_OK; 188 | if ((*toc_size << 1) > hyd_array_size(toc_perm_array)) { 189 | toc_perm = hyd_malloc_array(*toc_size << 1, sizeof(*toc_perm)); 190 | if (!toc_perm) { 191 | ret = HYD_NOMEM; 192 | goto end; 193 | } 194 | } 195 | calculate_toc_perm(encoder, *toc_size, toc_perm, frame_groups_x); 196 | if (*toc_size > hyd_array_size(temp_array)) { 197 | temp = hyd_malloc_array(*toc_size, sizeof(int32_t)); 198 | if (!temp) { 199 | ret = HYD_NOMEM; 200 | goto end; 201 | } 202 | } 203 | for (size_t i = 0; i < *toc_size; i++) 204 | temp[i] = i; 205 | size_t *lehmer; 206 | if (lehmer_init < *toc_size) { 207 | lehmer = calloc(*toc_size, sizeof(size_t)); 208 | if (!lehmer) { 209 | ret = HYD_NOMEM; 210 | goto end; 211 | } 212 | *lehmer_p = lehmer; 213 | } else { 214 | lehmer = *lehmer_p; 215 | } 216 | for (size_t i = 0; i < *toc_size; i++) { 217 | size_t k = 0; 218 | for (size_t j = 0; j < *toc_size; j++) { 219 | if (temp[j] == toc_perm[*toc_size + i]) { 220 | lehmer[i] = k; 221 | temp[j] = -1; 222 | } else if (temp[j] >= 0) { 223 | k++; 224 | } 225 | } 226 | } 227 | 228 | end: 229 | if (toc_perm != toc_perm_array) 230 | hyd_freep(&toc_perm); 231 | if (temp != temp_array) 232 | hyd_freep(&temp); 233 | return ret; 234 | } 235 | 236 | static HYDStatusCode write_frame_header(HYDEncoder *encoder) { 237 | HYDBitWriter *bw = &encoder->writer; 238 | HYDStatusCode ret; 239 | HYDEntropyStream toc_stream = { 0 }; 240 | size_t lehmer_array[64]; 241 | size_t *lehmer = lehmer_array; 242 | 243 | if (bw->overflow_state) 244 | return bw->overflow_state; 245 | 246 | hyd_write_zero_pad(bw); 247 | 248 | int is_last = encoder->one_frame || encoder->last_tile; 249 | int have_crop = !encoder->one_frame && 250 | !(encoder->metadata.width <= encoder->lfg->width 251 | && encoder->metadata.height <= encoder->lfg->height); 252 | 253 | /* all_default = 0 */ 254 | hyd_write(bw, 0, 1); 255 | /* frame_type = kRegularFrame or kSkipProgressive */ 256 | hyd_write(bw, is_last ? 0 : 3, 2); 257 | /* frame_encoding = VarDCT */ 258 | hyd_write(bw, 0, 1); 259 | /* flags = kSkipAdaptiveLFSmoothing */ 260 | hyd_write_u64(bw, 0x80); 261 | /* 262 | * upsampling = 0:2 263 | * x_qm_scale = 3:3 264 | * b_qm_scale = 2:3 265 | * num_passes = 0:2 266 | */ 267 | hyd_write(bw, 0x4C, 10); 268 | 269 | hyd_write_bool(bw, have_crop); 270 | 271 | if (have_crop) { 272 | // have_crop ==> !encoder->one_frame 273 | size_t frame_w = encoder->lfg->tile_count_x << 8; 274 | size_t frame_h = encoder->lfg->tile_count_y << 8; 275 | hyd_write_u32(bw, &frame_size_u32, hyd_pack_signed(encoder->lfg->x * frame_w)); 276 | hyd_write_u32(bw, &frame_size_u32, hyd_pack_signed(encoder->lfg->y * frame_h)); 277 | hyd_write_u32(bw, &frame_size_u32, encoder->lfg->width); 278 | hyd_write_u32(bw, &frame_size_u32, encoder->lfg->height); 279 | } 280 | 281 | /* blending_info.mode = kReplace */ 282 | hyd_write(bw, 0, 2); 283 | 284 | /* blending_info.source = 0 */ 285 | if (have_crop) 286 | hyd_write(bw, 0, 2); 287 | 288 | hyd_write_bool(bw, is_last); 289 | 290 | /* save_as_reference = 0 */ 291 | if (!is_last) 292 | hyd_write(bw, 0, 2); 293 | 294 | /* name_len = 0:2 */ 295 | hyd_write(bw, 0, 2); 296 | 297 | /* all_default = 0 */ 298 | hyd_write_bool(bw, 0); 299 | /* gab = 0 */ 300 | hyd_write_bool(bw, 0); 301 | /* epf_iters = 0 */ 302 | hyd_write(bw, 0, 2); 303 | /* extensions = 0 */ 304 | hyd_write(bw, 0, 2); 305 | 306 | /* 307 | * extensions = 0:2 308 | */ 309 | hyd_write(bw, 0, 2); 310 | 311 | size_t toc_size = 2; 312 | ret = get_lehmer_sequence(encoder, &toc_size, &lehmer, hyd_array_size(lehmer_array)); 313 | if (ret < HYD_ERROR_START) 314 | goto end; 315 | 316 | /* permuted toc */ 317 | if (toc_size > 1) { 318 | hyd_write_bool(bw, 1); 319 | ret = hyd_entropy_init_stream(&toc_stream, bw, 1 + toc_size, zerobuf, 320 | 8, 0, 0, 0, &encoder->error); 321 | if (ret < HYD_ERROR_START) 322 | goto end; 323 | ret = hyd_entropy_send_symbol(&toc_stream, 0, toc_size); 324 | if (ret < HYD_ERROR_START) 325 | goto end; 326 | for (size_t i = 0; i < toc_size; i++) { 327 | ret = hyd_entropy_send_symbol(&toc_stream, 0, lehmer[i]); 328 | if (ret < HYD_ERROR_START) 329 | goto end; 330 | } 331 | ret = hyd_prefix_finalize_stream(&toc_stream); 332 | if (ret < HYD_ERROR_START) 333 | goto end; 334 | } else { 335 | hyd_write_bool(bw, 0); 336 | } 337 | 338 | ret = hyd_write_zero_pad(bw); 339 | encoder->wrote_frame_header = 1; 340 | 341 | end: 342 | if (lehmer != lehmer_array) 343 | hyd_freep(&lehmer); 344 | return ret; 345 | } 346 | 347 | HYDStatusCode hyd_populate_lf_group(HYDEncoder *encoder, HYDLFGroup **lf_group_ptr, uint32_t tile_x, uint32_t tile_y) { 348 | size_t w, h; 349 | 350 | // check bounds 351 | if (encoder->one_frame) { 352 | w = h = 2048; 353 | } else { 354 | h = encoder->lfg->tile_count_y << 8; 355 | w = encoder->lfg->tile_count_x << 8; 356 | } 357 | 358 | if (tile_x >= (encoder->metadata.width + w - 1) / w || tile_y >= (encoder->metadata.height + h - 1) / h) { 359 | encoder->error = "tile out of bounds"; 360 | return HYD_API_ERROR; 361 | } 362 | 363 | HYDLFGroup *lf_group = &encoder->lfg[encoder->one_frame ? tile_y * encoder->lfg_count_x + tile_x : 0]; 364 | lf_group->y = tile_y; 365 | lf_group->x = tile_x; 366 | 367 | if (encoder->one_frame) { 368 | lf_group->tile_count_y = 8; 369 | lf_group->tile_count_x = 8; 370 | } 371 | 372 | lf_group->height = (tile_y + 1) * h > encoder->metadata.height ? encoder->metadata.height - tile_y * h : h; 373 | lf_group->width = (tile_x + 1) * w > encoder->metadata.width ? encoder->metadata.width - tile_x * w : w; 374 | lf_group->varblock_height = (lf_group->height + 7) >> 3; 375 | lf_group->varblock_width = (lf_group->width + 7) >> 3; 376 | lf_group->stride = lf_group->varblock_width << 3; 377 | 378 | if (lf_group_ptr) 379 | *lf_group_ptr = lf_group; 380 | 381 | return HYD_OK; 382 | } 383 | 384 | HYDStatusCode hyd_send_tile_pre(HYDEncoder *encoder, uint32_t tile_x, uint32_t tile_y, int is_last) { 385 | HYDStatusCode ret; 386 | 387 | HYDLFGroup *lf_group = NULL; 388 | ret = hyd_populate_lf_group(encoder, &lf_group, tile_x, tile_y); 389 | if (ret < HYD_ERROR_START) 390 | return ret; 391 | 392 | encoder->last_tile = is_last < 0 ? 393 | (tile_x + 1) * (lf_group->tile_count_x << 8) >= encoder->metadata.width && 394 | (tile_y + 1) * (lf_group->tile_count_y << 8) >= encoder->metadata.height 395 | : !!is_last; 396 | 397 | if (encoder->writer.overflow_state) 398 | return encoder->writer.overflow_state; 399 | 400 | if (!encoder->wrote_header) { 401 | ret = write_header(encoder); 402 | if (ret < HYD_ERROR_START) 403 | return ret; 404 | } 405 | 406 | if (!encoder->one_frame && !encoder->wrote_frame_header) { 407 | ret = write_frame_header(encoder); 408 | if (ret < HYD_ERROR_START) 409 | return ret; 410 | } 411 | 412 | size_t xyb_pixels = lf_group->varblock_height * lf_group->varblock_width * 64; 413 | ret = hyd_realloc_array_p(&encoder->xyb, xyb_pixels, sizeof(XYBEntry)); 414 | if (ret < HYD_ERROR_START) 415 | return ret; 416 | 417 | return HYD_OK; 418 | } 419 | 420 | static HYDStatusCode write_lf_global(HYDEncoder *encoder) { 421 | HYDBitWriter *bw = &encoder->working_writer; 422 | 423 | // LF channel quantization all_default 424 | hyd_write_bool(bw, 1); 425 | 426 | // quantizer globalScale = 32768 427 | hyd_write_u32(bw, &global_scale_table, 32768); 428 | // quantizer quantLF = 4 429 | hyd_write_u32(bw, &quant_lf_table, 4); 430 | // HF Block Context all_default 431 | hyd_write_bool(bw, 1); 432 | // LF Channel Correlation 433 | hyd_write_bool(bw, 1); 434 | // GlobalModular have_global_tree 435 | return hyd_write_bool(bw, 0); 436 | } 437 | 438 | static HYDStatusCode write_lf_group(HYDEncoder *encoder, HYDLFGroup *lf_group) { 439 | HYDStatusCode ret; 440 | HYDBitWriter *bw = &encoder->working_writer; 441 | // extra precision = 0 442 | hyd_write(bw, 0, 2); 443 | // use global tree 444 | hyd_write_bool(bw, 0); 445 | // wp_params all_default 446 | hyd_write_bool(bw, 1); 447 | // nb_transforms = 0 448 | hyd_write(bw, 0, 2); 449 | 450 | // write MA Tree 451 | HYDEntropyStream stream; 452 | ret = hyd_entropy_init_stream(&stream, bw, hyd_array_size(lf_ma_tree), 453 | zerobuf, 6, 0, 0, 0, &encoder->error); 454 | if (ret < HYD_ERROR_START) 455 | return ret; 456 | for (size_t i = 0; i < hyd_array_size(lf_ma_tree); i++) { 457 | ret = hyd_entropy_send_symbol(&stream, lf_ma_tree[i][0], lf_ma_tree[i][1]); 458 | if (ret < HYD_ERROR_START) 459 | return ret; 460 | } 461 | 462 | ret = hyd_prefix_finalize_stream(&stream); 463 | if (ret < HYD_ERROR_START) 464 | return ret; 465 | 466 | size_t nb_blocks = lf_group->varblock_height * lf_group->varblock_width; 467 | ret = hyd_entropy_init_stream(&stream, bw, 3 * nb_blocks, zerobuf, 468 | 1, 1, 1 << 14, 1, &encoder->error); 469 | if (ret < HYD_ERROR_START) 470 | return ret; 471 | ret = hyd_entropy_set_hybrid_config(&stream, 0, 0, 7, 1, 1); 472 | if (ret < HYD_ERROR_START) 473 | return ret; 474 | const float shift[3] = {8192.f, 1024.f, 512.f}; 475 | for (int i = 0; i < 3; i++) { 476 | const int c = i < 2 ? 1 - i : i; 477 | for (size_t vy = 0; vy < lf_group->varblock_height; vy++) { 478 | const size_t y = vy << 3; 479 | const size_t row = lf_group->stride * y; 480 | for (size_t vx = 0; vx < lf_group->varblock_width; vx++) { 481 | const size_t x = vx << 3; 482 | XYBEntry *xyb = &encoder->xyb[row + x]; 483 | xyb->xyb[c].i = xyb->xyb[c].f * shift[c]; 484 | const int32_t w = x > 0 ? xyb[-8].xyb[c].i : y > 0 ? xyb[-(lf_group->stride << 3)].xyb[c].i : 0; 485 | const int32_t n = y > 0 ? xyb[-(lf_group->stride << 3)].xyb[c].i : w; 486 | const int32_t nw = x > 0 && y > 0 ? xyb[-((lf_group->stride + 1) << 3)].xyb[c].i : w; 487 | const int32_t vp = w + n - nw; 488 | const int32_t min = hyd_min(w, n); 489 | /* a ^ b ^ c, when c == a or c == b, gives the other one */ 490 | const int32_t max = w ^ n ^ min; 491 | const int32_t v = hyd_clamp(vp, min, max); 492 | hyd_entropy_send_symbol(&stream, 0, hyd_pack_signed(xyb->xyb[c].i - v)); 493 | } 494 | } 495 | } 496 | ret = hyd_prefix_finalize_stream(&stream); 497 | if (ret < HYD_ERROR_START) 498 | return ret; 499 | hyd_write(bw, nb_blocks - 1, hyd_cllog2(nb_blocks)); 500 | hyd_write(bw, 0x2, 4); 501 | ret = hyd_entropy_init_stream(&stream, bw, 5, zerobuf, 502 | 6, 0, 0, 0, &encoder->error); 503 | if (ret < HYD_ERROR_START) 504 | return ret; 505 | hyd_entropy_send_symbol(&stream, 1, 0); 506 | hyd_entropy_send_symbol(&stream, 2, 0); 507 | hyd_entropy_send_symbol(&stream, 3, 0); 508 | hyd_entropy_send_symbol(&stream, 4, 0); 509 | hyd_entropy_send_symbol(&stream, 5, 0); 510 | ret = hyd_prefix_finalize_stream(&stream); 511 | if (ret < HYD_ERROR_START) 512 | return ret; 513 | size_t cfl_height = (lf_group->varblock_height + 7) >> 3; 514 | size_t cfl_width = (lf_group->varblock_width + 7) >> 3; 515 | size_t num_z_pre = 2 * cfl_width * cfl_height + nb_blocks; 516 | size_t num_sym = num_z_pre + 2 * nb_blocks; 517 | ret = hyd_entropy_init_stream(&stream, bw, num_sym, zerobuf, 1, 0, 29, 1, &encoder->error); 518 | if (ret < HYD_ERROR_START) 519 | return ret; 520 | for (size_t i = 0; i < num_z_pre; i++) 521 | hyd_entropy_send_symbol(&stream, 0, 0); 522 | for (size_t i = 0; i < nb_blocks; i++) 523 | hyd_entropy_send_symbol(&stream, 0, (hf_mult - 1) * 2); 524 | for (size_t i = 0; i < nb_blocks; i++) 525 | hyd_entropy_send_symbol(&stream, 0, 0); 526 | ret = hyd_prefix_finalize_stream(&stream); 527 | if (ret < HYD_ERROR_START) 528 | return ret; 529 | 530 | return bw->overflow_state; 531 | } 532 | 533 | static void forward_dct(HYDEncoder *encoder, HYDLFGroup *lf_group) { 534 | float scratchblock[2][8][8]; 535 | for (size_t c = 0; c < 3; c++) { 536 | for (size_t by = 0; by < lf_group->varblock_height; by++) { 537 | size_t vy = by << 3; 538 | for (size_t bx = 0; bx < lf_group->varblock_width; bx++) { 539 | memset(scratchblock, 0, sizeof(scratchblock)); 540 | size_t vx = bx << 3; 541 | for (size_t y = 0; y < 8; y++) { 542 | const size_t posy = (vy + y) * lf_group->stride + vx; 543 | scratchblock[0][y][0] = encoder->xyb[posy].xyb[c].f; 544 | for (size_t x = 1; x < 8; x++) 545 | scratchblock[0][y][0] += encoder->xyb[posy + x].xyb[c].f; 546 | scratchblock[0][y][0] *= 0.125f; 547 | for (size_t k = 1; k < 8; k++) { 548 | for (size_t n = 0; n < 8; n++) 549 | scratchblock[0][y][k] += encoder->xyb[posy + n].xyb[c].f * cosine_lut[k - 1][n]; 550 | } 551 | } 552 | for (size_t x = 0; x < 8; x++) { 553 | scratchblock[1][0][x] = scratchblock[0][0][x]; 554 | for (size_t y = 1; y < 8; y++) 555 | scratchblock[1][0][x] += scratchblock[0][y][x]; 556 | scratchblock[1][0][x] *= 0.125f; 557 | for (size_t k = 1; k < 8; k++) { 558 | for (size_t n = 0; n < 8; n++) 559 | scratchblock[1][k][x] += scratchblock[0][n][x] * cosine_lut[k - 1][n]; 560 | } 561 | } 562 | for (size_t y = 0; y < 8; y++) { 563 | size_t posy = (vy + y) * lf_group->stride + vx; 564 | for (size_t x = 0; x < 8; x++) 565 | encoder->xyb[posy + x].xyb[c].f = scratchblock[1][x][y]; 566 | } 567 | } 568 | } 569 | } 570 | } 571 | 572 | static uint8_t get_predicted_non_zeroes(uint8_t *nz, size_t y, size_t x, size_t w, int c) { 573 | if (!x && !y) 574 | return 32; 575 | if (!x) 576 | return nz[((y - 1) * w) * 3 + c]; 577 | if (!y) 578 | return nz[(x - 1) * 3 + c]; 579 | return (nz[((y - 1) * w + x) * 3 + c] + (uint32_t)nz[((y * w) + (x - 1)) * 3 + c] + 1) >> 1; 580 | } 581 | 582 | static size_t get_non_zero_context(size_t predicted, size_t block_context) { 583 | if (predicted < 8) 584 | return block_context + 15 * predicted; 585 | if (predicted > 64) 586 | predicted = 64; 587 | 588 | return block_context + 15 * (4 + (predicted >> 1)); 589 | } 590 | 591 | static HYDStatusCode initialize_hf_coeffs(HYDEncoder *encoder, HYDEntropyStream *stream, HYDLFGroup *lf_group, 592 | size_t num_non_zeroes, size_t *symbol_count, uint8_t *non_zeroes, 593 | size_t gindex) { 594 | HYDStatusCode ret; 595 | for (size_t gy = 0; gy < lf_group->tile_count_y; gy++) { 596 | if (gy << 8 >= lf_group->height) 597 | break; 598 | const size_t gh = (gy + 1) << 8 > lf_group->height ? 599 | lf_group->height - (gy << 8) : 256; 600 | const size_t gbh = (gh + 7) >> 3; 601 | for (size_t gx = 0; gx < lf_group->tile_count_x; gx++) { 602 | if (gx << 8 >= lf_group->width) 603 | break; 604 | const size_t gw = (gx + 1) << 8 > lf_group->width ? 605 | lf_group->width - (gx << 8) : 256; 606 | const size_t gbw = (gw + 7) >> 3; 607 | for (size_t by = 0; by < gbh; by++) { 608 | const size_t vy = (by << 3) + (gy << 8); 609 | for (size_t bx = 0; bx < gbw; bx++) { 610 | const size_t vx = (bx << 3) + (gx << 8); 611 | for (int i = 0; i < 3; i++) { 612 | int c = i < 2 ? 1 - i : i; 613 | uint8_t predicted = get_predicted_non_zeroes(non_zeroes, by, bx, gbw, c); 614 | size_t block_context = hf_block_cluster_map[13 * i]; 615 | size_t non_zero_context = get_non_zero_context(predicted, block_context); 616 | uint32_t non_zero_count = non_zeroes[(by * gbw + bx) * 3 + c]; 617 | ret = hyd_entropy_send_symbol(stream, non_zero_context, non_zero_count); 618 | symbol_count[gindex]++; 619 | if (ret < HYD_ERROR_START) 620 | return ret; 621 | if (!non_zero_count) 622 | continue; 623 | size_t hist_context = 458 * block_context + 555; 624 | for (int k = 0; k < 63; k++) { 625 | IntPos pos = natural_order[k + 1]; 626 | IntPos prev_pos = natural_order[k]; 627 | const size_t prev_pos_s = (vy + prev_pos.y) * lf_group->stride + (vx + prev_pos.x); 628 | const size_t pos_s = (vy + pos.y) * lf_group->stride + (vx + pos.x); 629 | int prev = k ? !!encoder->xyb[prev_pos_s].xyb[c].i : non_zero_count <= 4; 630 | size_t coeff_context = hist_context + prev + 631 | ((coeff_num_non_zero_context[non_zero_count] + coeff_freq_context[k + 1]) << 1); 632 | uint32_t value = hyd_pack_signed(encoder->xyb[pos_s].xyb[c].i); 633 | ret = hyd_entropy_send_symbol(stream, coeff_context, value); 634 | symbol_count[gindex]++; 635 | if (ret < HYD_ERROR_START) 636 | return ret; 637 | if (value && !--non_zero_count) 638 | break; 639 | } 640 | } 641 | } 642 | } 643 | non_zeroes += 3 << 10; 644 | gindex++; 645 | } 646 | } 647 | 648 | return encoder->working_writer.overflow_state; 649 | } 650 | 651 | static HYDStatusCode realloc_working_buffer(uint8_t **buffer, size_t *buffer_size) { 652 | size_t new_size = *buffer_size << 1; 653 | HYDStatusCode ret = hyd_realloc_p(buffer, new_size); 654 | if (ret < HYD_ERROR_START) 655 | return ret; 656 | *buffer_size = new_size; 657 | 658 | return HYD_OK; 659 | } 660 | 661 | HYDStatusCode hyd_encode_xyb_buffer(HYDEncoder *encoder, size_t tile_x, size_t tile_y) { 662 | uint8_t *non_zeroes = NULL; 663 | HYDStatusCode ret = HYD_OK; 664 | int need_buffer_init = !encoder->working_writer.buffer || !encoder->one_frame; 665 | if (!encoder->working_writer.buffer) { 666 | encoder->working_writer.buffer = malloc(1 << 12); 667 | if (!encoder->working_writer.buffer) { 668 | ret = HYD_NOMEM; 669 | goto end; 670 | } 671 | encoder->working_writer.buffer_len = 1 << 12; 672 | } 673 | if (need_buffer_init) { 674 | ret = hyd_init_bit_writer(&encoder->working_writer, encoder->working_writer.buffer, 675 | encoder->working_writer.buffer_len, 0, 0); 676 | encoder->copy_pos = 0; 677 | encoder->working_writer.realloc_func = &realloc_working_buffer; 678 | } 679 | 680 | if (ret < HYD_ERROR_START) 681 | goto end; 682 | 683 | const size_t lfid = encoder->one_frame ? tile_y * encoder->lfg_count_x + tile_x : 0; 684 | HYDLFGroup *lf_group = &encoder->lfg[lfid]; 685 | forward_dct(encoder, lf_group); 686 | size_t frame_h = encoder->one_frame ? encoder->metadata.height : encoder->lfg->height; 687 | size_t frame_w = encoder->one_frame ? encoder->metadata.width : encoder->lfg->width; 688 | size_t frame_groups_y = (frame_h + 255) >> 8; 689 | size_t frame_groups_x = (frame_w + 255) >> 8; 690 | size_t num_frame_groups = frame_groups_x * frame_groups_y; 691 | const size_t num_groups = ((lf_group->width + 255) >> 8) * ((lf_group->height + 255) >> 8); 692 | non_zeroes = calloc(3072, num_groups); 693 | if (!non_zeroes) { 694 | ret = HYD_NOMEM; 695 | goto end; 696 | } 697 | 698 | size_t non_zero_count = 0; 699 | size_t gindex = 0; 700 | const size_t lf_pad_w = lf_group->varblock_width << 3; 701 | for (size_t gy = 0; gy < lf_group->tile_count_y; gy++) { 702 | if (gy << 5 >= lf_group->varblock_height) 703 | break; 704 | const size_t gh = ((gy + 1) << 8) > lf_group->height ? 705 | lf_group->height - (gy << 8) : 256; 706 | const size_t gbh = (gh + 7) >> 3; 707 | for (size_t gx = 0; gx < lf_group->tile_count_x; gx++) { 708 | if (gx << 5 >= lf_group->varblock_width) 709 | break; 710 | const size_t gw = (gx + 1) << 8 > lf_group->width ? 711 | lf_group->width - (gx << 8) : 256; 712 | const size_t gbw = (gw + 7) >> 3; 713 | for (size_t by = 0; by < gbh; by++) { 714 | const size_t vy = (by << 3) + (gy << 8); 715 | for (size_t bx = 0; bx < gbw; bx++) { 716 | const size_t vx = (bx << 3) + (gx << 8); 717 | for (int i = 0; i < 3; i++) { 718 | size_t nzc = 0; 719 | for (int j = 1; j < 64; j++) { 720 | const size_t py = vy + natural_order[j].y; 721 | const size_t px = vx + natural_order[j].x; 722 | XYBEntry *xyb = &encoder->xyb[py * lf_pad_w + px]; 723 | const int32_t q = (int32_t)(xyb->xyb[i].f * (hf_quant_weights[i][j] * hf_mult)); 724 | xyb->xyb[i].i = hyd_abs(q) < 2 ? 0 : q; 725 | if (xyb->xyb[i].i) { 726 | non_zeroes[((gindex << 10) + by * gbw + bx) * 3 + i]++; 727 | nzc = j; 728 | } 729 | } 730 | non_zero_count += nzc; 731 | } 732 | } 733 | } 734 | gindex++; 735 | } 736 | } 737 | 738 | if (!encoder->tiles_sent) { 739 | if (num_frame_groups > 1) { 740 | const size_t count = 2 + encoder->lfg_per_frame + num_frame_groups; 741 | if (count > hyd_array_size(encoder->section_endpos_array)) { 742 | encoder->section_endpos = calloc(count, sizeof(size_t)); 743 | if (!encoder->section_endpos) { 744 | ret = HYD_NOMEM; 745 | goto end; 746 | } 747 | } else { 748 | memset(encoder->section_endpos_array, 0, sizeof(encoder->section_endpos_array)); 749 | encoder->section_endpos = encoder->section_endpos_array; 750 | } 751 | encoder->section_count = 0; 752 | } 753 | ret = write_lf_global(encoder); 754 | if (ret < HYD_ERROR_START) 755 | goto end; 756 | if (num_frame_groups > 1) { 757 | hyd_bitwriter_flush(&encoder->working_writer); 758 | encoder->section_endpos[encoder->section_count++] = encoder->working_writer.buffer_pos; 759 | } 760 | } 761 | 762 | ret = write_lf_group(encoder, lf_group); 763 | if (ret < HYD_ERROR_START) 764 | goto end; 765 | 766 | if (num_frame_groups > 1) { 767 | hyd_bitwriter_flush(&encoder->working_writer); 768 | encoder->section_endpos[encoder->section_count++] = encoder->working_writer.buffer_pos; 769 | } 770 | 771 | if (!encoder->tiles_sent) { 772 | const size_t num_syms = 1 << 12; 773 | memset(&encoder->hf_stream, 0, sizeof(HYDEntropyStream)); 774 | ret = hyd_entropy_init_stream(&encoder->hf_stream, &encoder->working_writer, 775 | num_syms, hf_cluster_map, 7425, 1, 0, 0, &encoder->error); 776 | if (ret < HYD_ERROR_START) 777 | goto end; 778 | ret = hyd_entropy_set_hybrid_config(&encoder->hf_stream, 0, 0, 4, 1, 0); 779 | if (ret < HYD_ERROR_START) 780 | goto end; 781 | } 782 | 783 | if (!encoder->hf_stream_barrier) 784 | encoder->hf_stream_barrier = calloc(num_frame_groups, sizeof(size_t)); 785 | if (!encoder->hf_stream_barrier) { 786 | ret = HYD_NOMEM; 787 | goto end; 788 | } 789 | 790 | ret = initialize_hf_coeffs(encoder, &encoder->hf_stream, lf_group, non_zero_count, 791 | encoder->hf_stream_barrier, non_zeroes, encoder->groups_encoded); 792 | if (ret < HYD_ERROR_START) 793 | goto end; 794 | if (encoder->one_frame) 795 | encoder->groups_encoded += num_groups; 796 | 797 | if (encoder->one_frame && !encoder->last_tile) 798 | goto end; 799 | 800 | // default params HFGlobal 801 | hyd_write_bool(&encoder->working_writer, 1); 802 | // num hf presets 803 | hyd_write(&encoder->working_writer, 0, hyd_cllog2(num_frame_groups)); 804 | // HF Pass order 805 | hyd_write(&encoder->working_writer, 2, 2); 806 | ret = hyd_ans_write_stream_header(&encoder->hf_stream); 807 | if (ret < HYD_ERROR_START) 808 | goto end; 809 | if (num_frame_groups > 1) { 810 | hyd_bitwriter_flush(&encoder->working_writer); 811 | encoder->section_endpos[encoder->section_count++] = encoder->working_writer.buffer_pos; 812 | } 813 | 814 | size_t soff = 0; 815 | for (size_t g = 0; g < num_frame_groups; g++) { 816 | ret = hyd_ans_write_stream_symbols(&encoder->hf_stream, soff, encoder->hf_stream_barrier[g]); 817 | if (ret < HYD_ERROR_START) 818 | goto end; 819 | soff += encoder->hf_stream_barrier[g]; 820 | if (num_frame_groups > 1) { 821 | hyd_bitwriter_flush(&encoder->working_writer); 822 | encoder->section_endpos[encoder->section_count++] = encoder->working_writer.buffer_pos; 823 | } 824 | } 825 | encoder->hf_stream.symbol_pos = 0; 826 | 827 | // write TOC to main buffer 828 | hyd_bitwriter_flush(&encoder->working_writer); 829 | 830 | if (!encoder->wrote_frame_header) { 831 | ret = write_frame_header(encoder); 832 | if (ret < HYD_ERROR_START) 833 | return ret; 834 | } 835 | 836 | hyd_write_zero_pad(&encoder->writer); 837 | 838 | if (num_frame_groups > 1) { 839 | size_t last_end_pos = 0; 840 | for (size_t index = 0; index < encoder->section_count; index++) { 841 | hyd_write_u32(&encoder->writer, &toc_table, encoder->section_endpos[index] - last_end_pos); 842 | last_end_pos = encoder->section_endpos[index]; 843 | } 844 | encoder->section_count = 0; 845 | } else { 846 | hyd_write_u32(&encoder->writer, &toc_table, encoder->working_writer.buffer_pos); 847 | } 848 | 849 | hyd_write_zero_pad(&encoder->writer); 850 | 851 | encoder->wrote_frame_header = 0; 852 | ret = hyd_flush(encoder); 853 | hyd_entropy_stream_destroy(&encoder->hf_stream); 854 | if (encoder->section_endpos != encoder->section_endpos_array) 855 | hyd_freep(&encoder->section_endpos); 856 | hyd_freep(&encoder->hf_stream_barrier); 857 | 858 | end: 859 | hyd_freep(&non_zeroes); 860 | return ret; 861 | } 862 | -------------------------------------------------------------------------------- /src/libhydrium/encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef HYD_ENCODER_H_ 2 | #define HYD_ENCODER_H_ 3 | 4 | #include 5 | 6 | #include "libhydrium/libhydrium.h" 7 | 8 | HYDStatusCode hyd_send_tile_pre(HYDEncoder *encoder, uint32_t tile_x, uint32_t tile_y, int is_last); 9 | HYDStatusCode hyd_encode_xyb_buffer(HYDEncoder *encoder, size_t tile_x, size_t tile_y); 10 | 11 | #endif /* HYD_ENCODER_H_ */ 12 | -------------------------------------------------------------------------------- /src/libhydrium/entropy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "bitwriter.h" 7 | #include "entropy.h" 8 | #include "internal.h" 9 | #include "math-functions.h" 10 | #include "memory.h" 11 | 12 | #define SF_CHAIN_CAPACITY (1 << 12) 13 | 14 | // State Flush. Monsieur Bond Wins. 15 | typedef struct StateFlush { 16 | uint16_t diff; 17 | uint16_t value; 18 | } StateFlush; 19 | 20 | typedef struct StateFlushChain { 21 | StateFlush state_flushes[SF_CHAIN_CAPACITY]; 22 | size_t pos; 23 | struct StateFlushChain *prev_chain; 24 | } StateFlushChain; 25 | 26 | typedef struct FrequencyEntry { 27 | int32_t token; 28 | uint32_t frequency; 29 | int32_t depth; 30 | int32_t max_depth; 31 | struct FrequencyEntry *left_child; 32 | struct FrequencyEntry *right_child; 33 | } FrequencyEntry; 34 | 35 | static const HYDVLCElement ans_dist_prefix_lengths[14] = { 36 | {17, 5}, {11, 4}, {15, 4}, {3, 4}, {9, 4}, {7, 4}, {4, 3}, 37 | {2, 3}, {5, 3}, {6, 3}, {0, 3}, {33, 6}, {1, 7}, {65, 7}, 38 | }; 39 | 40 | static const HYDHybridUintConfig lz77_len_conf = {7, 0, 0}; 41 | 42 | static const uint32_t prefix_zig_zag[18] = {1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 43 | 44 | static const HYDVLCElement prefix_level0_table[6] = { 45 | {0, 2}, {7, 4}, {3, 3}, {2, 2}, {1, 2}, {15, 4}, 46 | }; 47 | 48 | static const U32Table min_symbol_table = { 49 | .cpos = {224, 512, 4096, 8}, 50 | .upos = {0, 0, 0, 15}, 51 | }; 52 | static const U32Table min_length_table = { 53 | .cpos = {3, 4, 5, 9}, 54 | .upos = {0, 0, 2, 8}, 55 | }; 56 | 57 | static const uint64_t zero64 = 0; 58 | static const void *const zerobuf = &zero64; 59 | 60 | static const uint32_t br_lut[16] = { 61 | 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 62 | 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF, 63 | }; 64 | static inline uint32_t bitswap32(const uint32_t b) { 65 | uint32_t c = 0; 66 | for (unsigned i = 0; i < 32; i += 4) 67 | c |= br_lut[(b >> i) & 0xF] << (28 - i); 68 | return c; 69 | } 70 | 71 | static HYDStatusCode write_ans_u8(HYDBitWriter *bw, uint8_t b) { 72 | hyd_write_bool(bw, b); 73 | if (!b) 74 | return bw->overflow_state; 75 | int l = hyd_fllog2(b); 76 | hyd_write(bw, l, 3); 77 | return hyd_write(bw, b, l); 78 | } 79 | 80 | void hyd_entropy_stream_destroy(HYDEntropyStream *stream) { 81 | for (size_t i = 0; i < stream->num_clusters; i++) 82 | free(stream->frequencies[i]); 83 | free(stream->cluster_map); 84 | free(stream->symbols); 85 | for (size_t i = 0; i < stream->num_clusters; i++) { 86 | if (stream->alias_table[i]) { 87 | for (size_t j = 0; j < stream->alphabet_sizes[i]; j++) 88 | free(stream->alias_table[i][j].cutoffs); 89 | free(stream->alias_table[i]); 90 | } 91 | } 92 | for (size_t i = 0; i < stream->num_clusters; i++) 93 | free(stream->vlc_table[i]); 94 | memset(stream, 0, sizeof(HYDEntropyStream)); 95 | } 96 | 97 | HYDStatusCode hyd_entropy_set_hybrid_config(HYDEntropyStream *stream, uint8_t min_cluster, uint8_t to_cluster, 98 | int split_exponent, int msb_in_token, int lsb_in_token) { 99 | if (to_cluster && min_cluster >= to_cluster) { 100 | *stream->error = "min_cluster >= to_cluster"; 101 | return HYD_INTERNAL_ERROR; 102 | } 103 | 104 | for (uint8_t j = min_cluster; (!to_cluster || j < to_cluster) && j < stream->num_clusters; j++) { 105 | stream->configs[j].split_exponent = split_exponent; 106 | stream->configs[j].msb_in_token = msb_in_token; 107 | stream->configs[j].lsb_in_token = lsb_in_token; 108 | } 109 | 110 | return HYD_OK; 111 | } 112 | 113 | static HYDStatusCode write_cluster_map(HYDEntropyStream *stream) { 114 | HYDBitWriter *bw = stream->bw; 115 | 116 | if (stream->num_dists == 1) 117 | return HYD_OK; 118 | 119 | int nbits = hyd_cllog2(stream->num_clusters); 120 | 121 | if (nbits <= 3 && stream->num_dists * nbits <= 32) { 122 | // simple clustering 123 | hyd_write_bool(bw, 1); 124 | hyd_write(bw, nbits, 2); 125 | for (size_t i = 0; i < stream->num_dists; i++) 126 | hyd_write(bw, stream->cluster_map[i], nbits); 127 | return bw->overflow_state; 128 | } 129 | 130 | HYDEntropyStream nested; 131 | HYDStatusCode ret; 132 | // non simple clustering 133 | hyd_write_bool(bw, 0); 134 | // use mtf = true 135 | hyd_write_bool(bw, 1); 136 | ret = hyd_entropy_init_stream(&nested, bw, stream->num_dists, zerobuf, 137 | 1, 1, 64, 0, stream->error); 138 | if (ret < HYD_ERROR_START) 139 | goto fail; 140 | ret = hyd_entropy_set_hybrid_config(&nested, 0, 0, 4, 1, 0); 141 | if (ret < HYD_ERROR_START) 142 | goto fail; 143 | uint8_t mtf[256]; 144 | for (int i = 0; i < 256; i++) 145 | mtf[i] = i; 146 | for (uint32_t j = 0; j < stream->num_dists; j++) { 147 | uint8_t index = 0; 148 | for (int k = 0; k < 256; k++) { 149 | if (mtf[k] == stream->cluster_map[j]) { 150 | index = k; 151 | break; 152 | } 153 | } 154 | ret = hyd_entropy_send_symbol(&nested, 0, index); 155 | if (ret < HYD_ERROR_START) 156 | goto fail; 157 | if (index) { 158 | uint8_t value = mtf[index]; 159 | memmove(mtf + 1, mtf, index); 160 | mtf[0] = value; 161 | } 162 | } 163 | 164 | ret = hyd_prefix_finalize_stream(&nested); 165 | if (ret < HYD_ERROR_START) 166 | goto fail; 167 | 168 | return bw->overflow_state; 169 | 170 | fail: 171 | hyd_entropy_stream_destroy(&nested); 172 | return ret; 173 | } 174 | 175 | static HYDStatusCode write_hybrid_uint_config(HYDEntropyStream *stream, const HYDHybridUintConfig *config, 176 | int log_alphabet_size) { 177 | HYDBitWriter *bw = stream->bw; 178 | 179 | // split_exponent 180 | hyd_write(bw, config->split_exponent, hyd_cllog2(1 + log_alphabet_size)); 181 | if (config->split_exponent == log_alphabet_size) 182 | return bw->overflow_state; 183 | // msb_in_token 184 | hyd_write(bw, config->msb_in_token, 185 | hyd_cllog2(1 + config->split_exponent)); 186 | // lsb_in_token 187 | hyd_write(bw, config->lsb_in_token, 188 | hyd_cllog2(1 + config->split_exponent - config->msb_in_token)); 189 | return bw->overflow_state; 190 | } 191 | 192 | static HYDStatusCode generate_alias_mapping(HYDEntropyStream *stream, size_t cluster, 193 | int log_alphabet_size, int32_t uniq_pos) { 194 | int log_bucket_size = 12 - log_alphabet_size; 195 | uint32_t bucket_size = 1 << log_bucket_size; 196 | uint32_t table_size = 1 << log_alphabet_size; 197 | uint32_t symbols[256] = { 0 }; 198 | uint32_t cutoffs[256] = { 0 }; 199 | uint32_t offsets[256] = { 0 }; 200 | HYDAliasEntry *alias_table = stream->alias_table[cluster]; 201 | 202 | if (uniq_pos >= 0) { 203 | for (uint32_t i = 0; i < table_size; i++) { 204 | symbols[i] = uniq_pos; 205 | offsets[i] = i * bucket_size; 206 | } 207 | alias_table[uniq_pos].count = table_size; 208 | } else { 209 | size_t underfull_pos = 0; 210 | size_t overfull_pos = 0; 211 | uint8_t underfull[256]; 212 | uint8_t overfull[256]; 213 | for (size_t pos = 0; pos < stream->alphabet_sizes[cluster]; pos++) { 214 | cutoffs[pos] = stream->frequencies[cluster][pos]; 215 | if (cutoffs[pos] < bucket_size) 216 | underfull[underfull_pos++] = pos; 217 | else if (cutoffs[pos] > bucket_size) 218 | overfull[overfull_pos++] = pos; 219 | } 220 | 221 | for (uint32_t i = stream->alphabet_sizes[cluster]; i < table_size; i++) 222 | underfull[underfull_pos++] = i; 223 | 224 | while (overfull_pos) { 225 | if (!underfull_pos) { 226 | *stream->error = "empty underfull during alias table gen"; 227 | return HYD_INTERNAL_ERROR; 228 | } 229 | uint8_t u = underfull[--underfull_pos]; 230 | uint8_t o = overfull[--overfull_pos]; 231 | int32_t by = bucket_size - cutoffs[u]; 232 | offsets[u] = (cutoffs[o] -= by); 233 | symbols[u] = o; 234 | if (cutoffs[o] < bucket_size) 235 | underfull[underfull_pos++] = o; 236 | else if (cutoffs[o] > bucket_size) 237 | overfull[overfull_pos++] = o; 238 | } 239 | 240 | for (uint32_t sym = 0; sym < table_size; sym++) { 241 | if (cutoffs[sym] == bucket_size) { 242 | symbols[sym] = sym; 243 | cutoffs[sym] = offsets[sym] = 0; 244 | } else { 245 | offsets[sym] -= cutoffs[sym]; 246 | } 247 | alias_table[symbols[sym]].count++; 248 | } 249 | } 250 | 251 | for (uint32_t sym = 0; sym < stream->alphabet_sizes[cluster]; sym++) { 252 | alias_table[sym].cutoffs = calloc(3 * (alias_table[sym].count + 1), sizeof(int32_t)); 253 | if (!alias_table[sym].cutoffs) 254 | return HYD_NOMEM; 255 | memset(alias_table[sym].cutoffs, -1, 3 * (alias_table[sym].count + 1) * sizeof(int32_t)); 256 | alias_table[sym].offsets = alias_table[sym].cutoffs + alias_table[sym].count + 1; 257 | alias_table[sym].original = alias_table[sym].offsets + alias_table[sym].count + 1; 258 | alias_table[sym].offsets[0] = 0; 259 | alias_table[sym].cutoffs[0] = cutoffs[sym]; 260 | alias_table[sym].original[0] = sym; 261 | } 262 | 263 | for (uint32_t i = 0; i < table_size; i++) { 264 | size_t j = 1; 265 | while (alias_table[symbols[i]].cutoffs[j] >= 0) 266 | j++; 267 | alias_table[symbols[i]].cutoffs[j] = cutoffs[i]; 268 | alias_table[symbols[i]].offsets[j] = offsets[i]; 269 | alias_table[symbols[i]].original[j] = i; 270 | } 271 | 272 | return HYD_OK; 273 | } 274 | 275 | static int32_t write_ans_frequencies(HYDEntropyStream *stream, uint32_t *frequencies, uint32_t alphabet_size) { 276 | HYDBitWriter *bw = stream->bw; 277 | if (!alphabet_size) { 278 | // simple dist 279 | hyd_write(bw, 0x1, 2); 280 | write_ans_u8(bw, 0); 281 | return 0; 282 | } 283 | size_t total = 0; 284 | for (size_t k = 0; k < alphabet_size; k++) 285 | total += frequencies[k]; 286 | if (!total) { 287 | *stream->error = "All-zero ANS frequencies"; 288 | return HYD_INTERNAL_ERROR; 289 | } 290 | 291 | size_t new_total = 0; 292 | for (size_t k = 0; k < alphabet_size; k++) { 293 | if (!frequencies[k]) 294 | continue; 295 | frequencies[k] = (((uint64_t)frequencies[k] << 12) / total) & 0xFFFF; 296 | if (!frequencies[k]) 297 | frequencies[k] = 1; 298 | new_total += frequencies[k]; 299 | } 300 | 301 | size_t j = alphabet_size - 1; 302 | while (new_total > (1 << 12)) { 303 | size_t diff = new_total - (1 << 12); 304 | if (diff < frequencies[j]) { 305 | frequencies[j] -= diff; 306 | new_total -= diff; 307 | break; 308 | } else if (frequencies[j] > 1) { 309 | new_total -= frequencies[j] - 1; 310 | frequencies[j] = 1; 311 | } 312 | j--; 313 | } 314 | 315 | frequencies[0] += (1 << 12) - new_total; 316 | 317 | int32_t nz1 = -1, nz2 = -1, nzc = 0; 318 | 319 | for (size_t k = 0; k < alphabet_size; k++) { 320 | if (frequencies[k] == 1 << 12) { 321 | // simple dist 322 | hyd_write(bw, 0x1, 2); 323 | write_ans_u8(bw, k); 324 | return k; 325 | } 326 | if (!frequencies[k]) 327 | continue; 328 | if (++nzc > 2) 329 | break; 330 | if (nz1 < 0) { 331 | nz1 = k; 332 | } else if (frequencies[nz1] + frequencies[k] == 1 << 12) { 333 | nz2 = k; 334 | break; 335 | } 336 | } 337 | 338 | if (nz1 >= 0 && nz2 >= 0) { 339 | // simple dual peak dist 340 | hyd_write(bw, 0x3, 2); 341 | write_ans_u8(bw, nz1); 342 | write_ans_u8(bw, nz2); 343 | hyd_write(bw, frequencies[nz1], 12); 344 | return HYD_DEFAULT; 345 | } 346 | 347 | // simple dist and flat dist = 0 348 | hyd_write(bw, 0, 2); 349 | // len = 3 350 | hyd_write(bw, 0x7, 3); 351 | // shift = 13 352 | hyd_write(bw, 0x6, 3); 353 | write_ans_u8(bw, alphabet_size - 3); 354 | int log_counts[256]; 355 | size_t omit_pos = 0; 356 | size_t omit_log = 0; 357 | for (size_t k = 0; k < alphabet_size; k++) { 358 | log_counts[k] = frequencies[k] ? 1 + hyd_fllog2(frequencies[k]) : 0; 359 | hyd_write(bw, ans_dist_prefix_lengths[log_counts[k]].symbol, ans_dist_prefix_lengths[log_counts[k]].length); 360 | if (log_counts[k] > omit_log) { 361 | omit_log = log_counts[k]; 362 | omit_pos = k; 363 | } 364 | } 365 | for (size_t k = 0; k < alphabet_size; k++) { 366 | if (k == omit_pos || log_counts[k] <= 1) 367 | continue; 368 | hyd_write(bw, frequencies[k], log_counts[k] - 1); 369 | } 370 | 371 | return HYD_DEFAULT; 372 | } 373 | 374 | HYDStatusCode hyd_entropy_init_stream(HYDEntropyStream *stream, HYDBitWriter *bw, 375 | size_t symbol_count, const uint8_t *cluster_map, size_t num_dists, 376 | int custom_configs, uint32_t lz77_min_symbol, int modular, const char **error) { 377 | HYDStatusCode ret; 378 | memset(stream, 0, sizeof(HYDEntropyStream)); 379 | stream->error = error; 380 | if (!num_dists || !symbol_count) { 381 | *stream->error = "zero dist count or zero symbol count"; 382 | ret = HYD_INTERNAL_ERROR; 383 | goto fail; 384 | } 385 | if (lz77_min_symbol) { 386 | num_dists++; 387 | stream->lz77_min_length = 3; 388 | stream->lz77_min_symbol = lz77_min_symbol; 389 | } 390 | stream->num_dists = num_dists; 391 | stream->bw = bw; 392 | stream->modular = modular; 393 | stream->symbol_count = symbol_count; 394 | stream->cluster_map = malloc(num_dists); 395 | stream->symbols = hyd_malloc_array(stream->symbol_count, sizeof(HYDHybridSymbol)); 396 | if (!stream->cluster_map || !stream->symbols) { 397 | ret = HYD_NOMEM; 398 | goto fail; 399 | } 400 | memcpy(stream->cluster_map, cluster_map, num_dists - !!lz77_min_symbol); 401 | for (size_t i = 0; i < num_dists - !!lz77_min_symbol; i++) { 402 | if (stream->cluster_map[i] >= stream->num_clusters) 403 | stream->num_clusters = stream->cluster_map[i] + 1; 404 | } 405 | if (stream->num_clusters > num_dists) { 406 | *stream->error = "more clusters than dists"; 407 | ret = HYD_INTERNAL_ERROR; 408 | goto fail; 409 | } 410 | 411 | if (lz77_min_symbol) 412 | stream->cluster_map[num_dists - 1] = stream->num_clusters++; 413 | 414 | if (!custom_configs) { 415 | hyd_entropy_set_hybrid_config(stream, 0, stream->num_clusters - !!stream->lz77_min_symbol, 4, 1, 1); 416 | if (stream->lz77_min_symbol) 417 | hyd_entropy_set_hybrid_config(stream, stream->num_clusters - 1, stream->num_clusters, 7, 0, 0); 418 | } 419 | 420 | return HYD_OK; 421 | 422 | fail: 423 | hyd_entropy_stream_destroy(stream); 424 | return ret; 425 | } 426 | 427 | static void hybridize(uint32_t symbol, HYDHybridSymbol *hybrid_symbol, const HYDHybridUintConfig *config) { 428 | int split = 1 << config->split_exponent; 429 | if (symbol < split) { 430 | hybrid_symbol->token = symbol; 431 | hybrid_symbol->residue = hybrid_symbol->residue_bits = 0; 432 | } else { 433 | uint32_t n = hyd_fllog2(symbol) - config->lsb_in_token - config->msb_in_token; 434 | uint32_t low = symbol & ~(~UINT32_C(0) << config->lsb_in_token); 435 | symbol >>= config->lsb_in_token; 436 | hybrid_symbol->residue = symbol & ~(~UINT32_C(0) << n); 437 | symbol >>= n; 438 | uint32_t high = symbol & ~(~UINT32_C(0) << config->msb_in_token); 439 | hybrid_symbol->residue_bits = n; 440 | hybrid_symbol->token = split + (low | (high << config->lsb_in_token) | 441 | ((n - config->split_exponent + config->lsb_in_token + config->msb_in_token) << 442 | (config->msb_in_token + config->lsb_in_token))); 443 | } 444 | } 445 | 446 | static HYDStatusCode send_hybridized_symbol(HYDEntropyStream *stream, const HYDHybridSymbol *symbol) { 447 | if (stream->wrote_stream_header) { 448 | *stream->error = "Illegal send after stream header"; 449 | return HYD_INTERNAL_ERROR; 450 | } 451 | if (stream->symbol_pos >= stream->symbol_count) { 452 | HYDStatusCode ret = hyd_realloc_array_p(&stream->symbols, stream->symbol_count << 1, sizeof(HYDHybridSymbol)); 453 | if (ret < HYD_ERROR_START) 454 | return ret; 455 | stream->symbol_count <<= 1; 456 | } 457 | stream->symbols[stream->symbol_pos++] = *symbol; 458 | if (symbol->token >= stream->max_alphabet_size) 459 | stream->max_alphabet_size = 1 + symbol->token; 460 | if (symbol->token >= stream->alphabet_sizes[symbol->cluster]) 461 | stream->alphabet_sizes[symbol->cluster] = 1 + symbol->token; 462 | return HYD_OK; 463 | } 464 | 465 | static HYDStatusCode send_entropy_symbol0(HYDEntropyStream *stream, size_t dist, uint32_t symbol) { 466 | HYDHybridSymbol hybrid_symbol; 467 | hybrid_symbol.cluster = stream->cluster_map[dist]; 468 | hybridize(symbol, &hybrid_symbol, &stream->configs[hybrid_symbol.cluster]); 469 | return send_hybridized_symbol(stream, &hybrid_symbol); 470 | } 471 | 472 | static HYDStatusCode flush_lz77(HYDEntropyStream *stream) { 473 | HYDStatusCode ret; 474 | uint32_t last_symbol = stream->last_symbol - 1; 475 | 476 | if (stream->lz77_rle_count > stream->lz77_min_length) { 477 | uint32_t repeat_count = stream->lz77_rle_count - stream->lz77_min_length; 478 | HYDHybridSymbol hybrid_symbol; 479 | hybridize(repeat_count, &hybrid_symbol, &lz77_len_conf); 480 | hybrid_symbol.cluster = stream->cluster_map[stream->last_dist]; 481 | hybrid_symbol.token += stream->lz77_min_symbol; 482 | ret = send_hybridized_symbol(stream, &hybrid_symbol); 483 | if (ret < HYD_ERROR_START) 484 | return ret; 485 | ret = send_entropy_symbol0(stream, stream->num_dists - 1, !!stream->modular); 486 | if (ret < HYD_ERROR_START) 487 | return ret; 488 | } else if (stream->last_symbol && stream->lz77_rle_count) { 489 | for (uint32_t k = 0; k < stream->lz77_rle_count; k++) { 490 | ret = send_entropy_symbol0(stream, stream->last_dist, last_symbol); 491 | if (ret < HYD_ERROR_START) 492 | return ret; 493 | } 494 | } 495 | 496 | stream->lz77_rle_count = 0; 497 | 498 | return HYD_OK; 499 | } 500 | 501 | HYDStatusCode hyd_entropy_send_symbol(HYDEntropyStream *stream, size_t dist, uint32_t symbol) { 502 | HYDStatusCode ret = HYD_OK; 503 | 504 | if (!stream->lz77_min_symbol) 505 | return send_entropy_symbol0(stream, dist, symbol); 506 | 507 | if (stream->last_symbol == symbol + 1 && 508 | stream->cluster_map[stream->last_dist] == stream->cluster_map[dist]) { 509 | if (stream->lz77_rle_count < 127) { 510 | stream->lz77_rle_count++; 511 | return HYD_OK; 512 | } 513 | } 514 | 515 | ret = flush_lz77(stream); 516 | if (ret < HYD_ERROR_START) 517 | return ret; 518 | 519 | stream->last_symbol = symbol + 1; 520 | stream->last_dist = dist; 521 | 522 | return send_entropy_symbol0(stream, dist, symbol); 523 | } 524 | 525 | static HYDStatusCode stream_header_common(HYDEntropyStream *stream, int *las, int prefix_codes) { 526 | HYDStatusCode ret = HYD_OK; 527 | HYDBitWriter *bw = stream->bw; 528 | hyd_write_bool(bw, stream->lz77_min_symbol); 529 | if (stream->lz77_min_symbol) { 530 | ret = flush_lz77(stream); 531 | if (ret < HYD_ERROR_START) 532 | return ret; 533 | hyd_write_u32(bw, &min_symbol_table, stream->lz77_min_symbol); 534 | hyd_write_u32(bw, &min_length_table, stream->lz77_min_length); 535 | ret = write_hybrid_uint_config(stream, &lz77_len_conf, 8); 536 | if (ret < HYD_ERROR_START) 537 | return ret; 538 | } 539 | ret = write_cluster_map(stream); 540 | if (ret < HYD_ERROR_START) 541 | return ret; 542 | 543 | int log_alphabet_size = hyd_cllog2(stream->max_alphabet_size); 544 | if (log_alphabet_size < 5) 545 | log_alphabet_size = 5; 546 | *las = log_alphabet_size; 547 | 548 | hyd_write_bool(bw, prefix_codes); 549 | if (!prefix_codes) 550 | hyd_write(bw, log_alphabet_size - 5, 2); 551 | 552 | for (size_t i = 0; i < stream->num_clusters; i++) { 553 | ret = write_hybrid_uint_config(stream, &stream->configs[i], prefix_codes ? 15 : log_alphabet_size); 554 | if (ret < HYD_ERROR_START) 555 | return ret; 556 | } 557 | 558 | for (size_t c = 0; c < stream->num_clusters; c++) { 559 | if (!stream->alphabet_sizes[c]) 560 | continue; 561 | stream->frequencies[c] = calloc(stream->alphabet_sizes[c], sizeof(uint32_t)); 562 | if (!stream->frequencies[c]) 563 | return HYD_NOMEM; 564 | } 565 | for (size_t pos = 0; pos < stream->symbol_pos; pos++) { 566 | const HYDHybridSymbol *sym = &stream->symbols[pos]; 567 | stream->frequencies[sym->cluster][sym->token]++; 568 | } 569 | 570 | return bw->overflow_state; 571 | } 572 | 573 | static inline int huffman_compare(const FrequencyEntry *fa, const FrequencyEntry *fb) { 574 | return fa->frequency != fb->frequency ? 575 | (!fb->frequency ? -1 : !fa->frequency ? 1 : fa->frequency - fb->frequency) : 576 | (!fb->token ? -1 : !fa->token ? 1 : fa->token - fb->token); 577 | } 578 | 579 | static int32_t collect(FrequencyEntry *entry) { 580 | if (!entry) 581 | return 0; 582 | int32_t self = ++entry->depth; 583 | int32_t left = collect(entry->left_child); 584 | int32_t right = collect(entry->right_child); 585 | return entry->max_depth = hyd_max3(self, left, right); 586 | } 587 | 588 | static HYDStatusCode build_huffman_tree(HYDEntropyStream *stream, const uint32_t *frequencies, 589 | uint32_t *lengths, uint32_t alphabet_size, int32_t max_depth) { 590 | HYDStatusCode ret = HYD_OK; 591 | FrequencyEntry *tree = calloc((2 * alphabet_size - 1), sizeof(FrequencyEntry)); 592 | if (!tree) { 593 | ret = HYD_NOMEM; 594 | goto end; 595 | } 596 | 597 | uint32_t nz = 0; 598 | for (uint32_t token = 0; token < alphabet_size; token++) { 599 | tree[token].frequency = frequencies[token]; 600 | tree[token].token = 1 + token; 601 | tree[token].left_child = tree[token].right_child = NULL; 602 | if (frequencies[token]) 603 | nz++; 604 | } 605 | if (!nz) { 606 | *stream->error = "No nonzero frequencies"; 607 | ret = HYD_INTERNAL_ERROR; 608 | goto end; 609 | } 610 | 611 | if (max_depth < 0) 612 | max_depth = hyd_cllog2(alphabet_size + 1); 613 | 614 | for (uint32_t k = 0; k < alphabet_size - 1; k++) { 615 | int32_t smallest = -1; 616 | int32_t second = -1; 617 | int32_t target = max_depth - hyd_cllog2(nz--) + 1; 618 | for (uint32_t j = 2 * k; j < alphabet_size + k; j++) { 619 | if (!tree[j].frequency) 620 | continue; 621 | if (tree[j].max_depth >= target) 622 | continue; 623 | if (smallest < 0 || huffman_compare(&tree[j], &tree[smallest]) < 0) { 624 | second = smallest; 625 | smallest = j; 626 | } else if (second < 0 || huffman_compare(&tree[j], &tree[second]) < 0) { 627 | second = j; 628 | } 629 | } 630 | if (smallest < 0) { 631 | *stream->error = "couldn't find target"; 632 | ret = HYD_INTERNAL_ERROR; 633 | goto end; 634 | } 635 | hyd_swap(FrequencyEntry, tree[smallest], tree[2 * k]); 636 | if (second < 0) 637 | break; 638 | if (second == 2 * k) 639 | second = smallest; 640 | smallest = 2 * k; 641 | hyd_swap(FrequencyEntry, tree[second], tree[2 * k + 1]); 642 | second = smallest + 1; 643 | FrequencyEntry *entry = &tree[alphabet_size + k]; 644 | entry->frequency = tree[smallest].frequency + tree[second].frequency; 645 | entry->left_child = &tree[smallest]; 646 | entry->right_child = &tree[second]; 647 | collect(entry); 648 | } 649 | 650 | for (uint32_t j = 0; j < 2 * alphabet_size - 1; j++) { 651 | if (tree[j].token) 652 | lengths[tree[j].token - 1] = tree[j].depth; 653 | } 654 | 655 | end: 656 | free(tree); 657 | return ret; 658 | } 659 | 660 | static HYDStatusCode build_prefix_table(HYDEntropyStream *stream, HYDVLCElement *table, 661 | const uint32_t *lengths, uint32_t alphabet_size) { 662 | HYDStatusCode ret = HYD_OK; 663 | uint32_t *counts = NULL; 664 | HYDVLCElement *pre_table = NULL; 665 | size_t csize = hyd_max(alphabet_size + 1, 16); 666 | counts = calloc(csize, sizeof(uint32_t)); 667 | pre_table = hyd_malloc_array(alphabet_size, sizeof(HYDVLCElement)); 668 | if (!counts || !pre_table) { 669 | ret = HYD_NOMEM; 670 | goto end; 671 | } 672 | 673 | for (uint32_t j = 0; j < alphabet_size; j++) 674 | counts[lengths[j]]++; 675 | for (uint32_t j = 1; j < alphabet_size + 1; j++) 676 | counts[j] += counts[j - 1]; 677 | for (int32_t j = alphabet_size - 1; j >= 0; j--) { 678 | uint32_t index = --counts[lengths[j]]; 679 | pre_table[index].length = lengths[j]; 680 | pre_table[index].symbol = j; 681 | } 682 | 683 | uint64_t code = 0; 684 | for (int32_t j = 0; j < alphabet_size; j++) { 685 | if (!pre_table[j].length) 686 | continue; 687 | uint32_t s = pre_table[j].symbol; 688 | table[s].symbol = bitswap32(code); 689 | table[s].length = pre_table[j].length; 690 | code += UINT64_C(1) << (32 - pre_table[j].length); 691 | } 692 | 693 | if (code && code != (UINT64_C(1) << 32)) { 694 | *stream->error = "VLC codes do not add up"; 695 | ret = HYD_INTERNAL_ERROR; 696 | goto end; 697 | } 698 | 699 | end: 700 | hyd_freep(&counts); 701 | hyd_freep(&pre_table); 702 | return ret; 703 | } 704 | 705 | static void flush_zeroes(HYDBitWriter *bw, const HYDVLCElement *level1_table, uint32_t num_zeroes) { 706 | if (num_zeroes >= 3) { 707 | int32_t k = 0; 708 | uint32_t nz_residues[8]; 709 | while (num_zeroes > 10) { 710 | uint32_t new_num_zeroes = (num_zeroes + 13) / 8; 711 | nz_residues[k++] = num_zeroes - 8 * new_num_zeroes + 16; 712 | num_zeroes = new_num_zeroes; 713 | } 714 | nz_residues[k++] = num_zeroes; 715 | for (int32_t l = k - 1; l >= 0; l--) { 716 | hyd_write(bw, level1_table[17].symbol, level1_table[17].length); 717 | uint32_t res = nz_residues[l]; 718 | hyd_write(bw, res - 3, 3); 719 | } 720 | } else if (num_zeroes) { 721 | for (uint32_t k = 0; k < num_zeroes; k++) 722 | hyd_write(bw, level1_table[0].symbol, level1_table[0].length); 723 | } 724 | } 725 | 726 | static HYDStatusCode write_complex_prefix_lengths(HYDEntropyStream *stream, uint32_t alphabet_size, 727 | const uint32_t *lengths) { 728 | HYDBitWriter *bw = stream->bw; 729 | HYDStatusCode ret = HYD_OK; 730 | 731 | // hskip = 0 732 | hyd_write(bw, 0, 2); 733 | 734 | uint32_t level1_freqs[18] = { 0 }; 735 | 736 | uint32_t num_zeroes = 0; 737 | for (uint32_t j = 0; j < alphabet_size; j++) { 738 | uint32_t code = lengths[j]; 739 | if (!code) { 740 | num_zeroes++; 741 | continue; 742 | } 743 | if (num_zeroes >= 3) { 744 | while (num_zeroes > 10) { 745 | level1_freqs[17]++; 746 | num_zeroes = (num_zeroes + 13) / 8; 747 | } 748 | level1_freqs[17]++; 749 | } else { 750 | level1_freqs[0] += num_zeroes; 751 | } 752 | num_zeroes = 0; 753 | level1_freqs[code]++; 754 | } 755 | 756 | uint32_t level1_lengths[18] = { 0 }; 757 | ret = build_huffman_tree(stream, level1_freqs, level1_lengths, 18, 5); 758 | if (ret < HYD_ERROR_START) 759 | goto end; 760 | 761 | uint32_t total_code = 0; 762 | for (uint32_t j = 0; j < 18; j++) { 763 | uint32_t code = level1_lengths[prefix_zig_zag[j]]; 764 | hyd_write(bw, prefix_level0_table[code].symbol, 765 | prefix_level0_table[code].length); 766 | if (code) 767 | total_code += 32 >> code; 768 | if (total_code >= 32) 769 | break; 770 | } 771 | if (total_code && total_code != 32) { 772 | *stream->error = "level1 code total mismatch"; 773 | ret = HYD_INTERNAL_ERROR; 774 | goto end; 775 | } 776 | 777 | HYDVLCElement level1_table[18] = { 0 }; 778 | ret = build_prefix_table(stream, level1_table, level1_lengths, 18); 779 | if (ret < HYD_ERROR_START) 780 | goto end; 781 | 782 | total_code = 0; 783 | num_zeroes = 0; 784 | for (uint32_t j = 0; j < alphabet_size; j++) { 785 | uint32_t code = lengths[j]; 786 | if (!code) { 787 | num_zeroes++; 788 | continue; 789 | } 790 | flush_zeroes(bw, level1_table, num_zeroes); 791 | num_zeroes = 0; 792 | hyd_write(bw, level1_table[code].symbol, level1_table[code].length); 793 | total_code += 32768 >> code; 794 | if (total_code == 32768) 795 | break; 796 | } 797 | flush_zeroes(bw, level1_table, num_zeroes); 798 | 799 | end: 800 | return ret; 801 | } 802 | 803 | HYDStatusCode hyd_prefix_write_stream_header(HYDEntropyStream *stream) { 804 | HYDStatusCode ret; 805 | int log_alphabet_size; 806 | HYDBitWriter *bw = stream->bw; 807 | uint32_t *lengths = NULL; 808 | 809 | ret = stream_header_common(stream, &log_alphabet_size, 1); 810 | if (ret < HYD_ERROR_START) 811 | goto fail; 812 | 813 | for (size_t i = 0; i < stream->num_clusters; i++) { 814 | if (stream->alphabet_sizes[i] <= 1) { 815 | hyd_write_bool(bw, 0); 816 | continue; 817 | } 818 | hyd_write_bool(bw, 1); 819 | int n = hyd_fllog2(stream->alphabet_sizes[i] - 1); 820 | hyd_write(bw, n, 4); 821 | hyd_write(bw, stream->alphabet_sizes[i] - 1, n); 822 | } 823 | 824 | lengths = hyd_malloc_array(stream->max_alphabet_size, sizeof(uint32_t)); 825 | for (size_t i = 0; i < stream->num_clusters; i++) { 826 | stream->vlc_table[i] = calloc(stream->alphabet_sizes[i], sizeof(HYDVLCElement)); 827 | if (!stream->vlc_table[i]) { 828 | ret = HYD_NOMEM; 829 | goto fail; 830 | } 831 | } 832 | 833 | for (size_t i = 0; i < stream->num_clusters; i++) { 834 | const uint32_t alphabet_size = stream->alphabet_sizes[i]; 835 | if (alphabet_size <= 1) 836 | continue; 837 | const uint32_t *freqs = stream->frequencies[i]; 838 | memset(lengths, 0, stream->max_alphabet_size * sizeof(uint32_t)); 839 | HYDVLCElement *table = stream->vlc_table[i]; 840 | ret = build_huffman_tree(stream, freqs, lengths, alphabet_size, 15); 841 | if (ret < HYD_ERROR_START) 842 | goto fail; 843 | uint32_t nsym = 0; 844 | HYDVLCElement tokens[4] = { 0 }; 845 | for (uint32_t j = 0; j < alphabet_size; j++) { 846 | if (!lengths[j]) 847 | continue; 848 | if (nsym < 4) { 849 | tokens[nsym].symbol = j; 850 | tokens[nsym].length = lengths[j]; 851 | } 852 | if (++nsym > 4) 853 | break; 854 | } 855 | 856 | if (nsym > 4) { 857 | ret = write_complex_prefix_lengths(stream, alphabet_size, lengths); 858 | if (ret < HYD_ERROR_START) 859 | goto fail; 860 | ret = build_prefix_table(stream, table, lengths, alphabet_size); 861 | if (ret < HYD_ERROR_START) 862 | goto fail; 863 | continue; 864 | } 865 | 866 | if (nsym == 0) { 867 | nsym = 1; 868 | tokens[0].symbol = alphabet_size - 1; 869 | } 870 | 871 | // hskip = 1 872 | hyd_write(bw, 1, 2); 873 | hyd_write(bw, nsym - 1, 2); 874 | int log_alphabet_size = hyd_cllog2(alphabet_size); 875 | if (nsym == 3 && tokens[0].length != 1) { 876 | if (tokens[1].length == 1) { 877 | hyd_swap(HYDVLCElement, tokens[0], tokens[1]); 878 | } else { 879 | hyd_swap(HYDVLCElement, tokens[0], tokens[2]); 880 | } 881 | } 882 | int tree_select = 0; 883 | if (nsym == 4) { 884 | for (int i = 0; i < 4; i++) { 885 | if (tokens[i].length != 2) { 886 | tree_select = 1; 887 | break; 888 | } 889 | } 890 | if (tree_select && tokens[0].length != 1) { 891 | if (tokens[1].length == 1) { 892 | hyd_swap(HYDVLCElement, tokens[0], tokens[1]); 893 | } else if (tokens[2].length == 1) { 894 | hyd_swap(HYDVLCElement, tokens[0], tokens[2]); 895 | } else { 896 | hyd_swap(HYDVLCElement, tokens[0], tokens[3]); 897 | } 898 | } 899 | if (tree_select && tokens[1].length != 2) { 900 | if (tokens[2].length == 2) { 901 | hyd_swap(HYDVLCElement, tokens[1], tokens[2]); 902 | } else { 903 | hyd_swap(HYDVLCElement, tokens[1], tokens[3]); 904 | } 905 | } 906 | } 907 | for (int n = 0; n < nsym; n++) 908 | hyd_write(bw, tokens[n].symbol, log_alphabet_size); 909 | if (nsym == 4) 910 | hyd_write_bool(bw, tree_select); 911 | ret = build_prefix_table(stream, table, lengths, alphabet_size); 912 | if (ret < HYD_ERROR_START) 913 | goto fail; 914 | } 915 | 916 | free(lengths); 917 | stream->wrote_stream_header = 1; 918 | return bw->overflow_state; 919 | 920 | fail: 921 | free(lengths); 922 | hyd_entropy_stream_destroy(stream); 923 | return ret; 924 | } 925 | 926 | HYDStatusCode hyd_ans_write_stream_header(HYDEntropyStream *stream) { 927 | 928 | HYDStatusCode ret; 929 | int log_alphabet_size; 930 | HYDBitWriter *bw = stream->bw; 931 | 932 | ret = stream_header_common(stream, &log_alphabet_size, 0); 933 | if (ret < HYD_ERROR_START) 934 | goto fail; 935 | 936 | for (size_t i = 0; i < stream->num_clusters; i++) { 937 | if (!stream->alphabet_sizes[i]) 938 | continue; 939 | stream->alias_table[i] = calloc(stream->alphabet_sizes[i], sizeof(HYDAliasEntry)); 940 | if (!stream->alias_table[i]) { 941 | ret = HYD_NOMEM; 942 | goto fail; 943 | } 944 | } 945 | for (size_t i = 0; i < stream->num_clusters; i++) { 946 | int32_t uniq_pos = write_ans_frequencies(stream, stream->frequencies[i], stream->alphabet_sizes[i]); 947 | if (uniq_pos < HYD_ERROR_START) { 948 | ret = uniq_pos; 949 | goto fail; 950 | } 951 | if (!stream->alphabet_sizes[i]) 952 | continue; 953 | ret = generate_alias_mapping(stream, i, log_alphabet_size, uniq_pos); 954 | if (ret < HYD_ERROR_START) 955 | goto fail; 956 | } 957 | 958 | stream->wrote_stream_header = 1; 959 | 960 | return bw->overflow_state; 961 | 962 | fail: 963 | hyd_entropy_stream_destroy(stream); 964 | return ret; 965 | } 966 | 967 | HYDStatusCode hyd_prefix_write_stream_symbols(HYDEntropyStream *stream, size_t symbol_start, size_t symbol_count) { 968 | HYDBitWriter *bw = stream->bw; 969 | 970 | if (symbol_count + symbol_start > stream->symbol_pos) { 971 | *stream->error = "symbol out of bounds"; 972 | return HYD_INTERNAL_ERROR; 973 | } 974 | 975 | const HYDHybridSymbol *symbols = stream->symbols + symbol_start; 976 | for (size_t p = 0; p < symbol_count; p++) { 977 | size_t cluster = symbols[p].cluster; 978 | uint32_t token = symbols[p].token; 979 | const HYDVLCElement *entry = &stream->vlc_table[cluster][token]; 980 | hyd_write(bw, entry->symbol, entry->length); 981 | hyd_write(bw, symbols[p].residue, symbols[p].residue_bits); 982 | } 983 | 984 | return bw->overflow_state; 985 | } 986 | 987 | HYDStatusCode hyd_prefix_finalize_stream(HYDEntropyStream *stream) { 988 | HYDStatusCode ret = hyd_prefix_write_stream_header(stream); 989 | if (ret < HYD_ERROR_START) 990 | goto end; 991 | ret = hyd_prefix_write_stream_symbols(stream, 0, stream->symbol_pos); 992 | 993 | end: 994 | hyd_entropy_stream_destroy(stream); 995 | return ret; 996 | } 997 | 998 | static HYDStatusCode append_state_flush(StateFlushChain **flushes, uint16_t diff, uint16_t value) { 999 | if ((*flushes)->pos == SF_CHAIN_CAPACITY) { 1000 | StateFlushChain *chain = malloc(sizeof(*chain)); 1001 | if (!chain) 1002 | return HYD_NOMEM; 1003 | chain->pos = 0; 1004 | chain->prev_chain = *flushes; 1005 | *flushes = chain; 1006 | } 1007 | (*flushes)->state_flushes[(*flushes)->pos++] = (StateFlush){ 1008 | .diff = diff, 1009 | .value = value, 1010 | }; 1011 | 1012 | return HYD_OK; 1013 | } 1014 | 1015 | static StateFlush *pop_state_flush(StateFlushChain **flushes) { 1016 | if ((*flushes)->pos > 0) 1017 | return &(*flushes)->state_flushes[--(*flushes)->pos]; 1018 | StateFlushChain *prev_chain = (*flushes)->prev_chain; 1019 | if (!prev_chain) 1020 | return NULL; 1021 | free(*flushes); 1022 | *flushes = prev_chain; 1023 | return pop_state_flush(flushes); 1024 | } 1025 | 1026 | HYDStatusCode hyd_ans_write_stream_symbols(HYDEntropyStream *stream, size_t symbol_start, size_t symbol_count) { 1027 | HYDStatusCode ret = HYD_OK; 1028 | StateFlushChain *flushes = calloc(1, sizeof(*flushes)); 1029 | if (!flushes) { 1030 | ret = HYD_NOMEM; 1031 | goto end; 1032 | } 1033 | HYDBitWriter *bw = stream->bw; 1034 | int log_alphabet_size = hyd_cllog2(stream->max_alphabet_size); 1035 | if (log_alphabet_size < 5) 1036 | log_alphabet_size = 5; 1037 | const uint32_t log_bucket_size = 12 - log_alphabet_size; 1038 | const uint32_t pos_mask = ~(~UINT32_C(0) << log_bucket_size); 1039 | 1040 | if (symbol_count + symbol_start > stream->symbol_pos) { 1041 | *stream->error = "symbol out of bounds during ans flush"; 1042 | ret = HYD_INTERNAL_ERROR; 1043 | goto end; 1044 | } 1045 | 1046 | uint32_t state = 0x130000u; 1047 | const HYDHybridSymbol *symbols = stream->symbols + symbol_start; 1048 | size_t last_push = 0; 1049 | uint16_t last_value = 0; 1050 | for (size_t p2 = 0; p2 < symbol_count; p2++) { 1051 | const size_t p = symbol_count - p2 - 1; 1052 | const uint8_t symbol = symbols[p].token; 1053 | const size_t cluster = symbols[p].cluster; 1054 | const uint32_t freq = stream->frequencies[cluster][symbol]; 1055 | if ((state >> 20) >= freq) { 1056 | if (last_push) { 1057 | ret = append_state_flush(&flushes, last_push - p, last_value); 1058 | if (ret < HYD_ERROR_START) 1059 | goto end; 1060 | } 1061 | last_push = p; 1062 | last_value = state & 0xFFFF; 1063 | state >>= 16; 1064 | } 1065 | const uint32_t div = state / freq; 1066 | const uint32_t offset = state - div * freq; 1067 | uint32_t i, pos, j; 1068 | const HYDAliasEntry *alias = &stream->alias_table[cluster][symbol]; 1069 | for (j = 0; j <= alias->count; j++) { 1070 | pos = offset - alias->offsets[j]; 1071 | int32_t k = pos - alias->cutoffs[j]; 1072 | if (!(pos & ~pos_mask) && (j > 0 ? k >= 0 : k < 0)) { 1073 | i = alias->original[j]; 1074 | break; 1075 | } 1076 | } 1077 | if (j > alias->count) { 1078 | *stream->error = "alias table lookup failed"; 1079 | ret = HYD_INTERNAL_ERROR; 1080 | goto end; 1081 | } 1082 | state = (div << 12) | (i << log_bucket_size) | pos; 1083 | } 1084 | ret = append_state_flush(&flushes, last_push, last_value); 1085 | if (ret < HYD_ERROR_START) 1086 | goto end; 1087 | ret = append_state_flush(&flushes, 0, (state >> 16) & 0xFFFF); 1088 | if (ret < HYD_ERROR_START) 1089 | goto end; 1090 | ret = append_state_flush(&flushes, 0, state & 0xFFFF); 1091 | if (ret < HYD_ERROR_START) 1092 | goto end; 1093 | size_t last_pop = 0; 1094 | for (size_t p = 0; p < symbol_count; p++) { 1095 | const StateFlush *flush; 1096 | while ((flush = pop_state_flush(&flushes))) { 1097 | if (p - last_pop >= flush->diff) { 1098 | hyd_write(bw, flush->value, 16); 1099 | last_pop = p; 1100 | } else { 1101 | flushes->pos++; 1102 | break; 1103 | } 1104 | } 1105 | hyd_write(bw, symbols[p].residue, symbols[p].residue_bits); 1106 | } 1107 | 1108 | ret = bw->overflow_state; 1109 | 1110 | end: 1111 | while (flushes && flushes->prev_chain) { 1112 | StateFlushChain *prev = flushes->prev_chain; 1113 | free(flushes); 1114 | flushes = prev; 1115 | } 1116 | free(flushes); 1117 | return ret; 1118 | } 1119 | 1120 | HYDStatusCode hyd_ans_finalize_stream(HYDEntropyStream *stream) { 1121 | HYDStatusCode ret = hyd_ans_write_stream_header(stream); 1122 | if (ret < HYD_ERROR_START) 1123 | goto end; 1124 | ret = hyd_ans_write_stream_symbols(stream, 0, stream->symbol_pos); 1125 | 1126 | end: 1127 | hyd_entropy_stream_destroy(stream); 1128 | return ret; 1129 | } 1130 | -------------------------------------------------------------------------------- /src/libhydrium/entropy.h: -------------------------------------------------------------------------------- 1 | #ifndef HYD_ENTROPY_H_ 2 | #define HYD_ENTROPY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "bitwriter.h" 8 | 9 | typedef struct HYDHybridSymbol { 10 | uint16_t token; 11 | uint8_t cluster; 12 | uint8_t residue_bits; 13 | uint32_t residue; 14 | } HYDHybridSymbol; 15 | 16 | typedef struct HYDAliasEntry { 17 | size_t count; 18 | int32_t *cutoffs; 19 | int32_t *offsets; 20 | int32_t *original; 21 | } HYDAliasEntry; 22 | 23 | typedef struct HYDHybridUintConfig { 24 | uint8_t split_exponent; 25 | uint8_t msb_in_token; 26 | uint8_t lsb_in_token; 27 | } HYDHybridUintConfig; 28 | 29 | typedef struct HYDVLCElement { 30 | int32_t symbol; 31 | uint32_t length; 32 | } HYDVLCElement; 33 | 34 | typedef struct HYDEntropyStream { 35 | HYDBitWriter *bw; 36 | size_t num_dists; 37 | uint8_t *cluster_map; 38 | size_t num_clusters; 39 | size_t symbol_count; 40 | size_t symbol_pos; 41 | HYDHybridSymbol *symbols; 42 | uint16_t max_alphabet_size; 43 | uint16_t alphabet_sizes[256]; 44 | uint32_t *frequencies[256]; 45 | HYDHybridUintConfig configs[256]; 46 | int wrote_stream_header; 47 | 48 | // lz77 only 49 | uint32_t lz77_min_length; 50 | uint32_t lz77_min_symbol; 51 | uint32_t last_symbol; 52 | uint32_t last_dist; 53 | uint32_t lz77_rle_count; 54 | int modular; 55 | 56 | // prefix only 57 | HYDVLCElement *vlc_table[256]; 58 | 59 | // ans only 60 | HYDAliasEntry *alias_table[256]; 61 | 62 | // in case of error, break glass 63 | const char **error; 64 | } HYDEntropyStream; 65 | 66 | HYDStatusCode hyd_entropy_init_stream(HYDEntropyStream *stream, HYDBitWriter *bw, 67 | size_t symbol_count, const uint8_t *cluster_map, size_t num_dists, 68 | int custom_configs, uint32_t lz77_min_symbol, int modular, const char **error); 69 | HYDStatusCode hyd_entropy_set_hybrid_config(HYDEntropyStream *stream, uint8_t min_cluster, uint8_t to_cluster, 70 | int split_exponent, int msb_in_token, int lsb_in_token); 71 | HYDStatusCode hyd_entropy_send_symbol(HYDEntropyStream *stream, size_t dist, uint32_t symbol); 72 | 73 | HYDStatusCode hyd_prefix_write_stream_header(HYDEntropyStream *stream); 74 | HYDStatusCode hyd_prefix_write_stream_symbols(HYDEntropyStream *stream, size_t symbol_start, size_t symbol_count); 75 | 76 | /** 77 | * @brief write_stream_header, write_stream_symbols, and entropy_stream_destroy in one function 78 | * @return HYDStatusCode HYD_OK upon success, negative upon error. 79 | */ 80 | HYDStatusCode hyd_prefix_finalize_stream(HYDEntropyStream *stream); 81 | 82 | HYDStatusCode hyd_ans_write_stream_header(HYDEntropyStream *stream); 83 | HYDStatusCode hyd_ans_write_stream_symbols(HYDEntropyStream *stream, size_t symbol_offset, size_t symbol_count); 84 | 85 | /** 86 | * @brief write_stream_header, write_stream_symbols, and entropy_stream_destroy in one function 87 | * @return HYDStatusCode HYD_OK upon success, negative upon error. 88 | */ 89 | HYDStatusCode hyd_ans_finalize_stream(HYDEntropyStream *stream); 90 | 91 | void hyd_entropy_stream_destroy(HYDEntropyStream *stream); 92 | 93 | #endif /* HYD_ENTROPY_H_ */ 94 | -------------------------------------------------------------------------------- /src/libhydrium/format.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Pixel format conversion routines 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "libhydrium/libhydrium.h" 10 | #include "format.h" 11 | #include "internal.h" 12 | #include "math-functions.h" 13 | #include "memory.h" 14 | 15 | static inline float linearize(const float x) { 16 | if (x <= 0.0404482362771082f) 17 | return 0.07739938080495357f * x; 18 | return 0.003094300919832f + x * (-0.009982599f + x * (0.72007737769f + 0.2852804880f * x)); 19 | } 20 | 21 | static inline float hyd_cbrtf(const float x) { 22 | union { float f; uint32_t i; } z = { .f = x }; 23 | z.i = 0x548c39cbu - z.i / 3u; 24 | z.f *= 1.5015480449f - 0.534850249f * x * z.f * z.f * z.f; 25 | z.f *= 1.333333985f - 0.33333333f * x * z.f * z.f * z.f; 26 | return 1.0f / z.f; 27 | } 28 | 29 | static inline uint16_t f32_to_u16(const float x) { 30 | const int32_t y = (int32_t)(x * 65535.f + 0.5f); 31 | return hyd_clamp(y, 0, 65535); 32 | } 33 | 34 | static inline HYD_vec3_f32 rgb_to_xyb_f32(const HYD_vec3_f32 rgb) { 35 | const float lgamma = hyd_cbrtf(0.3f * rgb.v0 + 0.622f * rgb.v1 + 0.078f * rgb.v2 36 | + 0.0037930732552754493f) - 0.155954f; 37 | const float mgamma = hyd_cbrtf(0.23f * rgb.v0 + 0.692f * rgb.v1 + 0.078f * rgb.v2 38 | + 0.0037930732552754493f) - 0.155954f; 39 | const float sgamma = hyd_cbrtf(0.243423f * rgb.v0 + 0.204767f * rgb.v1 + 0.55181f * rgb.v2 40 | + 0.0037930732552754493f) - 0.155954f; 41 | const float y = (lgamma + mgamma) * 0.5f; 42 | const float x = y - mgamma; 43 | const float b = sgamma - y; 44 | return (HYD_vec3_f32) { .v0 = x, .v1 = y, .v2 = b, }; 45 | } 46 | 47 | static inline HYD_vec3_f32 rgb_to_xyb_u16(const float *output_lut, const HYD_vec3_u16 rgb) { 48 | const float lgamma = output_lut[((19661u * rgb.v0 + 40761u * rgb.v1 + 5112u * rgb.v2) >> 16) & 0xFFFFu]; 49 | const float mgamma = output_lut[((15073u * rgb.v0 + 45350u * rgb.v1 + 5112u * rgb.v2) >> 16) & 0xFFFFu]; 50 | const float sgamma = output_lut[((15953u * rgb.v0 + 13419u * rgb.v1 + 36163u * rgb.v2) >> 16) & 0xFFFFu]; 51 | const float y = (lgamma + mgamma) * 0.5f; 52 | const float x = y - mgamma; 53 | const float b = sgamma - y; 54 | return (HYD_vec3_f32) { .v0 = x, .v1 = y, .v2 = b, }; 55 | } 56 | 57 | static HYDStatusCode populate_input_lut(uint16_t **lut, const size_t size, const int need_linearize) { 58 | if (*lut) 59 | return HYD_OK; 60 | *lut = hyd_malloc_array(size, sizeof(**lut)); 61 | if (!*lut) 62 | return HYD_NOMEM; 63 | const float factor = 1.0f / (size - 1.0f); 64 | for (size_t i = 0; i < size; i++) { 65 | const float f = i * factor; 66 | (*lut)[i] = f32_to_u16(need_linearize ? linearize(f) : f); 67 | } 68 | 69 | return HYD_OK; 70 | } 71 | 72 | static HYDStatusCode populate_output_lut(float **lut, const size_t size) { 73 | if (*lut) 74 | return HYD_OK; 75 | *lut = hyd_malloc_array(size, sizeof(**lut)); 76 | if (!*lut) 77 | return HYD_NOMEM; 78 | const float factor = 1.0f / (size - 1.0f); 79 | for (size_t i = 0; i < size; i++) 80 | (*lut)[i] = hyd_cbrtf(i * factor + 0.0037930732552754493f) - 0.155954f; 81 | return HYD_OK; 82 | } 83 | 84 | #define process_lut(type_) \ 85 | static inline HYDStatusCode process_lut_ ## type_ (HYDEncoder *encoder, const type_ *const buffer[3], \ 86 | ptrdiff_t row_stride, ptrdiff_t pixel_stride, const HYDLFGroup *lfg, \ 87 | const uint16_t *input_lut, const float *bias_lut) { \ 88 | for (size_t y = 0; y < lfg->height; y++) { \ 89 | const ptrdiff_t y_off = y * row_stride; \ 90 | const size_t row = y * lfg->stride; \ 91 | for (size_t x = 0; x < lfg->width; x++) { \ 92 | const ptrdiff_t offset = y_off + x * pixel_stride; \ 93 | HYD_vec3_u16 rgbu16; \ 94 | rgbu16.v0 = input_lut[buffer[0][offset]]; \ 95 | rgbu16.v1 = input_lut[buffer[1][offset]]; \ 96 | rgbu16.v2 = input_lut[buffer[2][offset]]; \ 97 | HYD_vec3_f32 xyb = rgb_to_xyb_u16(bias_lut, rgbu16); \ 98 | XYBEntry *entry = &encoder->xyb[row + x]; \ 99 | entry->xyb[0].f = xyb.v0; \ 100 | entry->xyb[1].f = xyb.v1; \ 101 | entry->xyb[2].f = xyb.v2; \ 102 | } \ 103 | } \ 104 | return HYD_OK; \ 105 | } 106 | 107 | process_lut(uint8_t) 108 | process_lut(uint16_t) 109 | 110 | static inline HYDStatusCode process_lut_float(HYDEncoder *encoder, const float *const buffer[3], 111 | ptrdiff_t row_stride, ptrdiff_t pixel_stride, const HYDLFGroup *lfg, 112 | const int need_linearize) { 113 | for (size_t y = 0; y < lfg->height; y++) { 114 | const ptrdiff_t y_off = y * row_stride; 115 | const size_t row = y * lfg->stride; 116 | for (size_t x = 0; x < lfg->width; x++) { 117 | const ptrdiff_t offset = y_off + x * pixel_stride; 118 | HYD_vec3_f32 rgbf32; 119 | rgbf32.v0 = buffer[0][offset]; 120 | rgbf32.v1 = buffer[1][offset]; 121 | rgbf32.v2 = buffer[2][offset]; 122 | if (!hyd_isfinite(rgbf32.v0) || !hyd_isfinite(rgbf32.v1) || !hyd_isfinite(rgbf32.v2)) { 123 | encoder->error = "Invalid NaN Float"; 124 | return HYD_API_ERROR; 125 | } 126 | if (need_linearize) { 127 | rgbf32.v0 = linearize(rgbf32.v0); 128 | rgbf32.v1 = linearize(rgbf32.v1); 129 | rgbf32.v2 = linearize(rgbf32.v2); 130 | } 131 | HYD_vec3_f32 xyb = rgb_to_xyb_f32(rgbf32); 132 | XYBEntry *entry = &encoder->xyb[row + x]; 133 | entry->xyb[0].f = xyb.v0; 134 | entry->xyb[1].f = xyb.v1; 135 | entry->xyb[2].f = xyb.v2; 136 | } 137 | } 138 | return HYD_OK; 139 | } 140 | 141 | HYDStatusCode hyd_populate_xyb_buffer(HYDEncoder *encoder, const void *const buffer[3], 142 | ptrdiff_t row_stride, ptrdiff_t pixel_stride, size_t lf_group_id, 143 | HYDSampleFormat sample_fmt) { 144 | int need_linearize = !encoder->metadata.linear_light; 145 | uint16_t *input_lut; 146 | float *bias_lut; 147 | HYDStatusCode ret; 148 | if (sample_fmt == HYD_UINT8 || sample_fmt == HYD_UINT16) { 149 | uint16_t **lutss = sample_fmt == HYD_UINT8 ? &encoder->input_lut8 : &encoder->input_lut16; 150 | size_t lutsize = sample_fmt == HYD_UINT8 ? 256 : 65536; 151 | ret = populate_input_lut(lutss, lutsize, need_linearize); 152 | if (ret < HYD_ERROR_START) 153 | return ret; 154 | input_lut = *lutss; 155 | ret = populate_output_lut(&encoder->bias_cbrtf_lut, 65536); 156 | if (ret < HYD_ERROR_START) 157 | return ret; 158 | bias_lut = encoder->bias_cbrtf_lut; 159 | } 160 | const HYDLFGroup *lfg = &encoder->lfg[lf_group_id]; 161 | switch (sample_fmt) { 162 | case HYD_UINT8: { 163 | const uint8_t *const buf8[3] = { buffer[0], buffer[1], buffer[2] }; 164 | process_lut_uint8_t(encoder, buf8, row_stride, pixel_stride, lfg, input_lut, bias_lut); 165 | break; 166 | } 167 | case HYD_UINT16: { 168 | const uint16_t *const buf16[3] = { buffer[0], buffer[1], buffer[2] }; 169 | process_lut_uint16_t(encoder, buf16, row_stride, pixel_stride, lfg, input_lut, bias_lut); 170 | break; 171 | } 172 | case HYD_FLOAT32: { 173 | const float *const buf32[3] = { buffer[0], buffer[1], buffer[2] }; 174 | process_lut_float(encoder, buf32, row_stride, pixel_stride, lfg, need_linearize); 175 | break; 176 | } 177 | default: 178 | encoder->error = "Invalid Sample Format"; 179 | return HYD_API_ERROR; 180 | } 181 | const size_t residue_x = 8 - (lfg->width & 0x7u); 182 | if (residue_x != 8) { 183 | for (size_t y = 0; y < lfg->height; y++) { 184 | const size_t row = y * lfg->stride; 185 | memset(encoder->xyb + row + lfg->width, 0, residue_x * sizeof(XYBEntry)); 186 | } 187 | } 188 | const size_t residue_y = 8 - (lfg->height & 0x7u); 189 | if (residue_y != 8) 190 | memset(encoder->xyb + lfg->height * lfg->stride, 0, residue_y * lfg->stride * sizeof(XYBEntry)); 191 | 192 | return HYD_OK; 193 | } 194 | -------------------------------------------------------------------------------- /src/libhydrium/format.h: -------------------------------------------------------------------------------- 1 | #ifndef HYD_FORMAT_H_ 2 | #define HYD_FORMAT_H_ 3 | 4 | #include 5 | 6 | #include "libhydrium/libhydrium.h" 7 | 8 | typedef struct HYD_vec3_f32 { 9 | float v0, v1, v2; 10 | } HYD_vec3_f32; 11 | 12 | typedef struct HYD_vec3_u16 { 13 | uint16_t v0, v1, v2; 14 | } HYD_vec3_u16; 15 | 16 | HYDStatusCode hyd_populate_xyb_buffer(HYDEncoder *encoder, const void *const buffer[3], 17 | ptrdiff_t row_stride, ptrdiff_t pixel_stride, size_t lf_group_id, 18 | HYDSampleFormat sample_fmt); 19 | 20 | #endif /* HYD_FORMAT_H_ */ 21 | -------------------------------------------------------------------------------- /src/libhydrium/internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hydrium internal header implementation 3 | */ 4 | #ifndef HYDRIUM_INTERNAL_H_ 5 | #define HYDRIUM_INTERNAL_H_ 6 | 7 | #include "libhydrium/libhydrium.h" 8 | 9 | #include "bitwriter.h" 10 | #include "entropy.h" 11 | #include "format.h" 12 | 13 | typedef struct HYDLFGroup { 14 | size_t tile_count_x, tile_count_y; 15 | size_t x, y; 16 | size_t width, height; 17 | size_t varblock_width, varblock_height; 18 | size_t stride; 19 | } HYDLFGroup; 20 | 21 | typedef struct XYBEntry { 22 | union { 23 | int32_t i; 24 | float f; 25 | } xyb[3]; 26 | } XYBEntry; 27 | 28 | /* opaque structure */ 29 | struct HYDEncoder { 30 | HYDImageMetadata metadata; 31 | HYDEntropyStream hf_stream; 32 | 33 | XYBEntry *xyb; 34 | 35 | int one_frame; 36 | int last_tile; 37 | 38 | size_t lfg_count_y, lfg_count_x; 39 | size_t lfg_per_frame; 40 | 41 | HYDLFGroup lfg_array[64]; 42 | HYDLFGroup *lfg; 43 | 44 | size_t lfg_perm_array[64]; 45 | size_t *lfg_perm; 46 | 47 | uint8_t *out; 48 | size_t out_pos; 49 | size_t out_len; 50 | 51 | HYDBitWriter writer; 52 | HYDBitWriter working_writer; 53 | size_t copy_pos; 54 | 55 | int wrote_header; 56 | int wrote_frame_header; 57 | size_t tiles_sent; 58 | int level10; 59 | 60 | size_t section_endpos_array[64]; 61 | size_t *section_endpos; 62 | size_t section_count; 63 | 64 | size_t *hf_stream_barrier; 65 | size_t groups_encoded; 66 | 67 | const char *error; 68 | 69 | uint16_t *input_lut8; 70 | uint16_t *input_lut16; 71 | float *bias_cbrtf_lut; 72 | }; 73 | 74 | HYDStatusCode hyd_populate_lf_group(HYDEncoder *encoder, HYDLFGroup **lf_group, uint32_t tile_x, uint32_t tile_y); 75 | 76 | #endif /* HYDRIUM_INTERNAL_H_ */ 77 | -------------------------------------------------------------------------------- /src/libhydrium/libhydrium.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libhydrium/hydrium.c 3 | * 4 | * This is the main libhydrium API entry point, implementation. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include "encoder.h" 11 | #include "format.h" 12 | #include "internal.h" 13 | #include "math-functions.h" 14 | #include "memory.h" 15 | 16 | HYDRIUM_EXPORT HYDEncoder *hyd_encoder_new(void) { 17 | HYDEncoder *ret = calloc(1, sizeof(HYDEncoder)); 18 | return ret; 19 | } 20 | 21 | HYDRIUM_EXPORT HYDStatusCode hyd_encoder_destroy(HYDEncoder *encoder) { 22 | if (!encoder) 23 | return HYD_OK; 24 | hyd_entropy_stream_destroy(&encoder->hf_stream); 25 | if (encoder->section_endpos != encoder->section_endpos_array) 26 | hyd_freep(&encoder->section_endpos); 27 | hyd_freep(&encoder->hf_stream_barrier); 28 | hyd_freep(&encoder->working_writer.buffer); 29 | hyd_freep(&encoder->xyb); 30 | if (encoder->lfg != encoder->lfg_array) 31 | hyd_freep(&encoder->lfg); 32 | if (encoder->lfg_perm != encoder->lfg_perm_array) 33 | hyd_freep(&encoder->lfg_perm); 34 | hyd_freep(&encoder->input_lut8); 35 | hyd_freep(&encoder->input_lut16); 36 | hyd_freep(&encoder->bias_cbrtf_lut); 37 | hyd_freep(&encoder); 38 | return HYD_OK; 39 | } 40 | 41 | HYDRIUM_EXPORT HYDStatusCode hyd_set_metadata(HYDEncoder *encoder, const HYDImageMetadata *metadata) { 42 | HYDStatusCode ret = HYD_OK; 43 | if (!metadata->width || !metadata->height) { 44 | encoder->error = "invalid zero-width or zero-height"; 45 | return HYD_API_ERROR; 46 | } 47 | const uint64_t width64 = metadata->width; 48 | const uint64_t height64 = metadata->height; 49 | if (width64 > UINT64_C(1) << 30 || height64 > UINT64_C(1) << 30) { 50 | encoder->error = "width or height out of bounds"; 51 | return HYD_API_ERROR; 52 | } 53 | 54 | /* won't overflow due to above check */ 55 | if (width64 * height64 > UINT64_C(1) << 40) { 56 | encoder->error = "width times height out of bounds"; 57 | return HYD_API_ERROR; 58 | } 59 | 60 | encoder->metadata = *metadata; 61 | 62 | if (width64 > (1 << 20) || height64 > (1 << 20) || width64 * height64 > (1 << 28)) 63 | encoder->level10 = 1; 64 | 65 | if (metadata->tile_size_shift_x < -1 || metadata->tile_size_shift_x > 3) { 66 | encoder->error = "tile_size_shift_y must be between -1 and 3"; 67 | return HYD_API_ERROR; 68 | } 69 | if (metadata->tile_size_shift_y < -1 || metadata->tile_size_shift_y > 3) { 70 | encoder->error = "tile_size_shift_y must be between -1 and 3"; 71 | return HYD_API_ERROR; 72 | } 73 | 74 | encoder->one_frame = metadata->tile_size_shift_x < 0 || metadata->tile_size_shift_y < 0; 75 | encoder->lfg_count_y = (metadata->height + 2047) >> 11; 76 | encoder->lfg_count_x = (metadata->width + 2047) >> 11; 77 | encoder->lfg_per_frame = encoder->one_frame ? encoder->lfg_count_y * encoder->lfg_count_x : 1; 78 | if (encoder->lfg != encoder->lfg_array) 79 | hyd_freep(&encoder->lfg); 80 | if (encoder->lfg_per_frame > hyd_array_size(encoder->lfg_array)) { 81 | encoder->lfg = hyd_malloc_array(encoder->lfg_per_frame, sizeof(*encoder->lfg)); 82 | if (!encoder->lfg) 83 | return HYD_NOMEM; 84 | } else { 85 | encoder->lfg = encoder->lfg_array; 86 | } 87 | 88 | if (encoder->one_frame) { 89 | if (encoder->lfg_perm != encoder->lfg_perm_array) 90 | hyd_freep(&encoder->lfg_perm); 91 | if (encoder->lfg_per_frame > hyd_array_size(encoder->lfg_perm_array)) { 92 | encoder->lfg_perm = hyd_malloc_array(encoder->lfg_per_frame, sizeof(*encoder->lfg_perm)); 93 | if (!encoder->lfg_perm) 94 | return HYD_NOMEM; 95 | } else { 96 | encoder->lfg_perm = encoder->lfg_perm_array; 97 | } 98 | for (size_t y = 0; y < encoder->lfg_count_y; y++) { 99 | for (size_t x = 0; x < encoder->lfg_count_x; x++) { 100 | ret = hyd_populate_lf_group(encoder, NULL, x, y); 101 | if (ret < HYD_ERROR_START) 102 | return ret; 103 | } 104 | } 105 | } else { 106 | encoder->lfg->tile_count_y = 1 << metadata->tile_size_shift_y; 107 | encoder->lfg->tile_count_x = 1 << metadata->tile_size_shift_x; 108 | } 109 | 110 | return HYD_OK; 111 | } 112 | 113 | HYDRIUM_EXPORT HYDStatusCode hyd_provide_output_buffer(HYDEncoder *encoder, uint8_t *buffer, size_t buffer_len) { 114 | if (buffer_len < 64) { 115 | encoder->error = "provided buffer must be at least 64 bytes long"; 116 | return HYD_API_ERROR; 117 | } 118 | if (encoder->out) { 119 | encoder->error = "buffer was already provided"; 120 | return HYD_API_ERROR; 121 | } 122 | if (!buffer) { 123 | encoder->error = "buffer may not be null"; 124 | return HYD_API_ERROR; 125 | } 126 | encoder->out = buffer; 127 | encoder->out_len = buffer_len; 128 | encoder->out_pos = 0; 129 | if (encoder->writer.overflow_pos > 0) { 130 | memcpy(encoder->out, encoder->writer.overflow, encoder->writer.overflow_pos); 131 | encoder->out_pos = encoder->writer.overflow_pos; 132 | } 133 | return hyd_init_bit_writer(&encoder->writer, buffer, buffer_len, encoder->writer.cache, encoder->writer.cache_bits); 134 | } 135 | 136 | HYDRIUM_EXPORT HYDStatusCode hyd_release_output_buffer(HYDEncoder *encoder, size_t *written) { 137 | if (!encoder->out) { 138 | encoder->error = "buffer was never provided"; 139 | return HYD_API_ERROR; 140 | } 141 | *written = encoder->writer.buffer_pos; 142 | encoder->out = NULL; 143 | return encoder->writer.overflow_state; 144 | } 145 | 146 | HYDRIUM_EXPORT HYDStatusCode hyd_flush(HYDEncoder *encoder) { 147 | if (encoder->one_frame && !encoder->last_tile) 148 | return HYD_OK; 149 | if (!encoder->out) { 150 | encoder->error = "buffer was never provided"; 151 | return HYD_API_ERROR; 152 | } 153 | hyd_bitwriter_flush(&encoder->writer); 154 | size_t tocopy = encoder->writer.buffer_len - encoder->writer.buffer_pos; 155 | if (tocopy > encoder->working_writer.buffer_pos - encoder->copy_pos) 156 | tocopy = encoder->working_writer.buffer_pos - encoder->copy_pos; 157 | memcpy(encoder->writer.buffer + encoder->writer.buffer_pos, 158 | encoder->working_writer.buffer + encoder->copy_pos, tocopy); 159 | encoder->writer.buffer_pos += tocopy; 160 | encoder->copy_pos += tocopy; 161 | if (encoder->copy_pos >= encoder->working_writer.buffer_pos) 162 | return HYD_OK; 163 | 164 | return HYD_NEED_MORE_OUTPUT; 165 | } 166 | 167 | HYDRIUM_EXPORT const char *hyd_error_message_get(HYDEncoder *encoder) { 168 | return encoder->error; 169 | } 170 | 171 | HYDRIUM_EXPORT HYDStatusCode hyd_send_tile(HYDEncoder *encoder, const void *const buffer[3], 172 | uint32_t tile_x, uint32_t tile_y, ptrdiff_t row_stride, 173 | ptrdiff_t pixel_stride, int is_last, HYDSampleFormat sample_fmt) { 174 | HYDStatusCode ret; 175 | 176 | if (sample_fmt != HYD_UINT8 && sample_fmt != HYD_UINT16 && sample_fmt != HYD_FLOAT32) { 177 | encoder->error = "Invalid Sample Format"; 178 | return HYD_API_ERROR; 179 | } 180 | 181 | ret = hyd_send_tile_pre(encoder, tile_x, tile_y, is_last); 182 | if (ret < HYD_ERROR_START) 183 | return ret; 184 | 185 | size_t lfid = encoder->one_frame ? tile_y * encoder->lfg_count_x + tile_x : 0; 186 | 187 | ret = hyd_populate_xyb_buffer(encoder, buffer, row_stride, pixel_stride, lfid, sample_fmt); 188 | if (ret < HYD_ERROR_START) 189 | return ret; 190 | 191 | if (encoder->one_frame) 192 | encoder->lfg_perm[encoder->tiles_sent] = lfid; 193 | 194 | ret = hyd_encode_xyb_buffer(encoder, tile_x, tile_y); 195 | if (ret < HYD_ERROR_START) 196 | return ret; 197 | 198 | if (encoder->one_frame) 199 | encoder->tiles_sent++; 200 | 201 | return HYD_OK; 202 | } 203 | -------------------------------------------------------------------------------- /src/libhydrium/math-functions.h: -------------------------------------------------------------------------------- 1 | #ifndef HYDRIUM_MATH_FUNCTIONS_H_ 2 | #define HYDRIUM_MATH_FUNCTIONS_H_ 3 | 4 | #include 5 | 6 | #if defined(__GNUC__) || defined(__clang__) 7 | #define hyd_fllog2(n) (__builtin_clzll(1) - __builtin_clzll((n)|1)) 8 | #elif defined(_MSC_VER) 9 | #include 10 | static inline int __builtin_clzll(const unsigned long long x) { 11 | #ifdef _WIN64 12 | return (int)_lzcnt_u64(x); 13 | #else 14 | return ((unsigned)(x >> 32)) ? __builtin_clz((unsigned)(x >> 32)) : 32 + __builtin_clz((unsigned)x); 15 | #endif 16 | } 17 | #define hyd_fllog2(n) (__builtin_clzll(1) - __builtin_clzll((n)|1)) 18 | #else /* _MSC_VER */ 19 | static inline int hyd_fllog2(unsigned long long n) { 20 | int i = 0; 21 | if (n >= (1ULL << 32)) { 22 | i += 32; 23 | n >>= 32; 24 | } 25 | if (n >= (1ULL << 16)) { 26 | i += 16; 27 | n >>= 16; 28 | } 29 | if (n >= (1ULL << 8)) { 30 | i += 8; 31 | n >>= 8; 32 | } 33 | if (n >= (1ULL << 4)) { 34 | i += 4; 35 | n >>= 4; 36 | } 37 | if (n >= (1ULL << 2)) { 38 | i += 2; 39 | n >>= 2; 40 | } 41 | if (n >= (1ULL << 1)) 42 | ++i; 43 | return i; 44 | } 45 | #endif /* __GNUC__ || __clang__ || _MSC_VER */ 46 | 47 | /* ceil(log2(n)) */ 48 | static inline int hyd_cllog2(const unsigned long long n) { 49 | return hyd_fllog2(n) + !!(n & (n - 1)); 50 | } 51 | 52 | static inline uint32_t hyd_pack_signed(const int32_t v) { 53 | return ((uint32_t)v << 1) ^ -!!(v & UINT32_C(0x80000000)); 54 | } 55 | 56 | static inline int hyd_isfinite(const float x) { 57 | const union { uint32_t i; float f; } z = { .f = x }; 58 | return (z.i & 0x7f800000) != 0x7f800000; 59 | } 60 | 61 | #define hyd_abs(a) ((a) < 0 ? -(a) : (a)) 62 | #define hyd_array_size(a) (sizeof((a))/sizeof(*(a))) 63 | #define hyd_max(a, b) ((a) > (b) ? (a) : (b)) 64 | #define hyd_min(a, b) ((a) < (b) ? (a) : (b)) 65 | #define hyd_clamp(v, min, max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) 66 | #define hyd_max3(a, b, c) hyd_max((a), hyd_max((b), (c))) 67 | #define hyd_swap(type, a, b) do {\ 68 | const type __hyd_swap_temp = (b); (b) = (a); (a) = __hyd_swap_temp;\ 69 | } while (0) 70 | 71 | #endif /* HYDRIUM_MATH_FUNCTIONS_H_ */ 72 | -------------------------------------------------------------------------------- /src/libhydrium/memory.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libhydrium memory.c 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "libhydrium/libhydrium.h" 10 | #include "memory.h" 11 | 12 | #define total_size_check(n, s, retv) \ 13 | size_t total_size = (n) * (s); \ 14 | if ((s) && total_size / (s) != (n)) \ 15 | return (retv); 16 | 17 | void *hyd_malloc_array(size_t nmemb, size_t size) { 18 | total_size_check(nmemb, size, NULL); 19 | return malloc(total_size); 20 | } 21 | 22 | void *hyd_realloc_array(void *ptr, size_t nmemb, size_t size) { 23 | total_size_check(nmemb, size, NULL); 24 | return realloc(ptr, total_size); 25 | } 26 | 27 | HYDStatusCode hyd_realloc_p(void *buffer, size_t buffer_size) { 28 | void **bufferp = buffer; 29 | size_t new_size = buffer_size << 1; 30 | void *new_buffer = realloc(*bufferp, new_size); 31 | if (!new_buffer) 32 | return HYD_NOMEM; 33 | *bufferp = new_buffer; 34 | 35 | return HYD_OK; 36 | } 37 | 38 | HYDStatusCode hyd_realloc_array_p(void *buffer, size_t nmemb, size_t size) { 39 | total_size_check(nmemb, size, HYD_NOMEM); 40 | return hyd_realloc_p(buffer, total_size); 41 | } 42 | -------------------------------------------------------------------------------- /src/libhydrium/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef HYDRIUM_MEMORY_H_ 2 | #define HYDRIUM_MEMORY_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "libhydrium/libhydrium.h" 8 | 9 | static inline void hyd_freep(void *ptr) { 10 | void **ptrv = ptr; 11 | if (ptrv && *ptrv) { 12 | free(*ptrv); 13 | *ptrv = NULL; 14 | } 15 | } 16 | 17 | void *hyd_malloc_array(size_t nmemb, size_t size); 18 | void *hyd_realloc_array(void *ptr, size_t nmemb, size_t size); 19 | HYDStatusCode hyd_realloc_p(void *buffer, size_t buffer_size); 20 | HYDStatusCode hyd_realloc_array_p(void *buffer, size_t nmemb, size_t size); 21 | 22 | #endif /* HYDRIUM_MEMORY_H_ */ 23 | -------------------------------------------------------------------------------- /subprojects/spng.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/randy408/libspng/ 3 | revision = head 4 | depth = 1 5 | -------------------------------------------------------------------------------- /windows-cross.ini: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = 'x86_64-w64-mingw32-gcc' 3 | ar = 'x86_64-w64-mingw32-ar' 4 | strip = 'x86_64-w64-mingw32-strip' 5 | ranlib = 'x86_64-w64-mingw32-ranlib' 6 | windres = 'x86_64-w64-mingw32-windres' 7 | exe_wrapper = 'wine64' 8 | 9 | [host_machine] 10 | system = 'windows' 11 | cpu_family = 'x86_64' 12 | cpu = 'x86_64' 13 | endian = 'little' 14 | --------------------------------------------------------------------------------