1 /* 2 * jsimd_arm64.c 3 * 4 * Copyright 2009 Pierre Ossman <ossman (at) cendio.se> for Cendio AB 5 * Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies). 6 * Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander. 7 * Copyright (C) 2015-2016, Matthieu Darbois. 8 * 9 * Based on the x86 SIMD extension for IJG JPEG library, 10 * Copyright (C) 1999-2006, MIYASAKA Masaru. 11 * For conditions of distribution and use, see copyright notice in jsimdext.inc 12 * 13 * This file contains the interface between the "normal" portions 14 * of the library and the SIMD implementations when running on a 15 * 64-bit ARM architecture. 16 */ 17 18 #define JPEG_INTERNALS 19 #include "../jinclude.h" 20 #include "../jpeglib.h" 21 #include "../jsimd.h" 22 #include "../jdct.h" 23 #include "../jsimddct.h" 24 #include "jsimd.h" 25 26 #include <stdio.h> 27 #include <string.h> 28 #include <ctype.h> 29 30 #define JSIMD_FASTLD3 1 31 #define JSIMD_FASTST3 2 32 #define JSIMD_FASTTBL 4 33 34 static unsigned int simd_support = ~0; 35 static unsigned int simd_huffman = 1; 36 static unsigned int simd_features = JSIMD_FASTLD3 | JSIMD_FASTST3 | 37 JSIMD_FASTTBL; 38 39 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__) 40 41 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024) 42 43 LOCAL(int) 44 check_cpuinfo (char *buffer, const char *field, char *value) 45 { 46 char *p; 47 if (*value == 0) 48 return 0; 49 if (strncmp(buffer, field, strlen(field)) != 0) 50 return 0; 51 buffer += strlen(field); 52 while (isspace(*buffer)) 53 buffer++; 54 55 /* Check if 'value' is present in the buffer as a separate word */ 56 while ((p = strstr(buffer, value))) { 57 if (p > buffer && !isspace(*(p - 1))) { 58 buffer++; 59 continue; 60 } 61 p += strlen(value); 62 if (*p != 0 && !isspace(*p)) { 63 buffer++; 64 continue; 65 } 66 return 1; 67 } 68 return 0; 69 } 70 71 LOCAL(int) 72 parse_proc_cpuinfo (int bufsize) 73 { 74 char *buffer = (char *)malloc(bufsize); 75 FILE *fd; 76 77 if (!buffer) 78 return 0; 79 80 fd = fopen("/proc/cpuinfo", "r"); 81 if (fd) { 82 while (fgets(buffer, bufsize, fd)) { 83 if (!strchr(buffer, '\n') && !feof(fd)) { 84 /* "impossible" happened - insufficient size of the buffer! */ 85 fclose(fd); 86 free(buffer); 87 return 0; 88 } 89 if (check_cpuinfo(buffer, "CPU part", "0xd03") || 90 check_cpuinfo(buffer, "CPU part", "0xd07")) 91 /* The Cortex-A53 has a slow tbl implementation. We can gain a few 92 percent speedup by disabling the use of that instruction. The 93 speedup on Cortex-A57 is more subtle but still measurable. */ 94 simd_features &= ~JSIMD_FASTTBL; 95 else if (check_cpuinfo(buffer, "CPU part", "0x0a1")) 96 /* The SIMD version of Huffman encoding is slower than the C version on 97 Cavium ThunderX. Also, ld3 and st3 are abyssmally slow on that 98 CPU. */ 99 simd_huffman = simd_features = 0; 100 } 101 fclose(fd); 102 } 103 free(buffer); 104 return 1; 105 } 106 107 #endif 108 109 /* 110 * Check what SIMD accelerations are supported. 111 * 112 * FIXME: This code is racy under a multi-threaded environment. 113 */ 114 115 /* 116 * ARMv8 architectures support NEON extensions by default. 117 * It is no longer optional as it was with ARMv7. 118 */ 119 120 121 LOCAL(void) 122 init_simd (void) 123 { 124 char *env = NULL; 125 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__) 126 int bufsize = 1024; /* an initial guess for the line buffer size limit */ 127 #endif 128 129 if (simd_support != ~0U) 130 return; 131 132 simd_support = 0; 133 134 simd_support |= JSIMD_ARM_NEON; 135 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__) 136 while (!parse_proc_cpuinfo(bufsize)) { 137 bufsize *= 2; 138 if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT) 139 break; 140 } 141 #endif 142 143 /* Force different settings through environment variables */ 144 env = getenv("JSIMD_FORCENEON"); 145 if ((env != NULL) && (strcmp(env, "1") == 0)) 146 simd_support = JSIMD_ARM_NEON; 147 env = getenv("JSIMD_FORCENONE"); 148 if ((env != NULL) && (strcmp(env, "1") == 0)) 149 simd_support = 0; 150 env = getenv("JSIMD_NOHUFFENC"); 151 if ((env != NULL) && (strcmp(env, "1") == 0)) 152 simd_huffman = 0; 153 env = getenv("JSIMD_FASTLD3"); 154 if ((env != NULL) && (strcmp(env, "1") == 0)) 155 simd_features |= JSIMD_FASTLD3; 156 if ((env != NULL) && (strcmp(env, "0") == 0)) 157 simd_features &= ~JSIMD_FASTLD3; 158 env = getenv("JSIMD_FASTST3"); 159 if ((env != NULL) && (strcmp(env, "1") == 0)) 160 simd_features |= JSIMD_FASTST3; 161 if ((env != NULL) && (strcmp(env, "0") == 0)) 162 simd_features &= ~JSIMD_FASTST3; 163 } 164 165 GLOBAL(int) 166 jsimd_can_rgb_ycc (void) 167 { 168 init_simd(); 169 170 /* The code is optimised for these values only */ 171 if (BITS_IN_JSAMPLE != 8) 172 return 0; 173 if (sizeof(JDIMENSION) != 4) 174 return 0; 175 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4)) 176 return 0; 177 178 if (simd_support & JSIMD_ARM_NEON) 179 return 1; 180 181 return 0; 182 } 183 184 GLOBAL(int) 185 jsimd_can_rgb_gray (void) 186 { 187 init_simd(); 188 189 return 0; 190 } 191 192 GLOBAL(int) 193 jsimd_can_ycc_rgb (void) 194 { 195 init_simd(); 196 197 /* The code is optimised for these values only */ 198 if (BITS_IN_JSAMPLE != 8) 199 return 0; 200 if (sizeof(JDIMENSION) != 4) 201 return 0; 202 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4)) 203 return 0; 204 205 if (simd_support & JSIMD_ARM_NEON) 206 return 1; 207 208 return 0; 209 } 210 211 GLOBAL(int) 212 jsimd_can_ycc_rgb565 (void) 213 { 214 init_simd(); 215 216 /* The code is optimised for these values only */ 217 if (BITS_IN_JSAMPLE != 8) 218 return 0; 219 if (sizeof(JDIMENSION) != 4) 220 return 0; 221 222 if (simd_support & JSIMD_ARM_NEON) 223 return 1; 224 225 return 0; 226 } 227 228 GLOBAL(void) 229 jsimd_rgb_ycc_convert (j_compress_ptr cinfo, 230 JSAMPARRAY input_buf, JSAMPIMAGE output_buf, 231 JDIMENSION output_row, int num_rows) 232 { 233 void (*neonfct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int); 234 235 switch(cinfo->in_color_space) { 236 case JCS_EXT_RGB: 237 if (simd_features & JSIMD_FASTLD3) 238 neonfct=jsimd_extrgb_ycc_convert_neon; 239 else 240 neonfct=jsimd_extrgb_ycc_convert_neon_slowld3; 241 break; 242 case JCS_EXT_RGBX: 243 case JCS_EXT_RGBA: 244 neonfct=jsimd_extrgbx_ycc_convert_neon; 245 break; 246 case JCS_EXT_BGR: 247 if (simd_features & JSIMD_FASTLD3) 248 neonfct=jsimd_extbgr_ycc_convert_neon; 249 else 250 neonfct=jsimd_extbgr_ycc_convert_neon_slowld3; 251 break; 252 case JCS_EXT_BGRX: 253 case JCS_EXT_BGRA: 254 neonfct=jsimd_extbgrx_ycc_convert_neon; 255 break; 256 case JCS_EXT_XBGR: 257 case JCS_EXT_ABGR: 258 neonfct=jsimd_extxbgr_ycc_convert_neon; 259 break; 260 case JCS_EXT_XRGB: 261 case JCS_EXT_ARGB: 262 neonfct=jsimd_extxrgb_ycc_convert_neon; 263 break; 264 default: 265 if (simd_features & JSIMD_FASTLD3) 266 neonfct=jsimd_extrgb_ycc_convert_neon; 267 else 268 neonfct=jsimd_extrgb_ycc_convert_neon_slowld3; 269 break; 270 } 271 272 neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows); 273 } 274 275 GLOBAL(void) 276 jsimd_rgb_gray_convert (j_compress_ptr cinfo, 277 JSAMPARRAY input_buf, JSAMPIMAGE output_buf, 278 JDIMENSION output_row, int num_rows) 279 { 280 } 281 282 GLOBAL(void) 283 jsimd_ycc_rgb_convert (j_decompress_ptr cinfo, 284 JSAMPIMAGE input_buf, JDIMENSION input_row, 285 JSAMPARRAY output_buf, int num_rows) 286 { 287 void (*neonfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int); 288 289 switch(cinfo->out_color_space) { 290 case JCS_EXT_RGB: 291 if (simd_features & JSIMD_FASTST3) 292 neonfct=jsimd_ycc_extrgb_convert_neon; 293 else 294 neonfct=jsimd_ycc_extrgb_convert_neon_slowst3; 295 break; 296 case JCS_EXT_RGBX: 297 case JCS_EXT_RGBA: 298 neonfct=jsimd_ycc_extrgbx_convert_neon; 299 break; 300 case JCS_EXT_BGR: 301 if (simd_features & JSIMD_FASTST3) 302 neonfct=jsimd_ycc_extbgr_convert_neon; 303 else 304 neonfct=jsimd_ycc_extbgr_convert_neon_slowst3; 305 break; 306 case JCS_EXT_BGRX: 307 case JCS_EXT_BGRA: 308 neonfct=jsimd_ycc_extbgrx_convert_neon; 309 break; 310 case JCS_EXT_XBGR: 311 case JCS_EXT_ABGR: 312 neonfct=jsimd_ycc_extxbgr_convert_neon; 313 break; 314 case JCS_EXT_XRGB: 315 case JCS_EXT_ARGB: 316 neonfct=jsimd_ycc_extxrgb_convert_neon; 317 break; 318 default: 319 if (simd_features & JSIMD_FASTST3) 320 neonfct=jsimd_ycc_extrgb_convert_neon; 321 else 322 neonfct=jsimd_ycc_extrgb_convert_neon_slowst3; 323 break; 324 } 325 326 neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows); 327 } 328 329 GLOBAL(void) 330 jsimd_ycc_rgb565_convert (j_decompress_ptr cinfo, 331 JSAMPIMAGE input_buf, JDIMENSION input_row, 332 JSAMPARRAY output_buf, int num_rows) 333 { 334 jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row, 335 output_buf, num_rows); 336 } 337 338 GLOBAL(int) 339 jsimd_can_h2v2_downsample (void) 340 { 341 init_simd(); 342 343 /* The code is optimised for these values only */ 344 if (BITS_IN_JSAMPLE != 8) 345 return 0; 346 if (DCTSIZE != 8) 347 return 0; 348 if (sizeof(JDIMENSION) != 4) 349 return 0; 350 351 if (simd_support & JSIMD_ARM_NEON) 352 return 1; 353 354 return 0; 355 } 356 357 GLOBAL(int) 358 jsimd_can_h2v1_downsample (void) 359 { 360 init_simd(); 361 362 /* The code is optimised for these values only */ 363 if (BITS_IN_JSAMPLE != 8) 364 return 0; 365 if (DCTSIZE != 8) 366 return 0; 367 if (sizeof(JDIMENSION) != 4) 368 return 0; 369 370 if (simd_support & JSIMD_ARM_NEON) 371 return 1; 372 373 return 0; 374 } 375 376 GLOBAL(void) 377 jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, 378 JSAMPARRAY input_data, JSAMPARRAY output_data) 379 { 380 jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor, 381 compptr->v_samp_factor, compptr->width_in_blocks, 382 input_data, output_data); 383 } 384 385 GLOBAL(void) 386 jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, 387 JSAMPARRAY input_data, JSAMPARRAY output_data) 388 { 389 jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor, 390 compptr->v_samp_factor, compptr->width_in_blocks, 391 input_data, output_data); 392 } 393 394 GLOBAL(int) 395 jsimd_can_h2v2_upsample (void) 396 { 397 init_simd(); 398 399 return 0; 400 } 401 402 GLOBAL(int) 403 jsimd_can_h2v1_upsample (void) 404 { 405 init_simd(); 406 407 return 0; 408 } 409 410 GLOBAL(void) 411 jsimd_h2v2_upsample (j_decompress_ptr cinfo, 412 jpeg_component_info *compptr, 413 JSAMPARRAY input_data, 414 JSAMPARRAY *output_data_ptr) 415 { 416 } 417 418 GLOBAL(void) 419 jsimd_h2v1_upsample (j_decompress_ptr cinfo, 420 jpeg_component_info *compptr, 421 JSAMPARRAY input_data, 422 JSAMPARRAY *output_data_ptr) 423 { 424 } 425 426 GLOBAL(int) 427 jsimd_can_h2v2_fancy_upsample (void) 428 { 429 init_simd(); 430 431 return 0; 432 } 433 434 GLOBAL(int) 435 jsimd_can_h2v1_fancy_upsample (void) 436 { 437 init_simd(); 438 439 return 0; 440 } 441 442 GLOBAL(void) 443 jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo, 444 jpeg_component_info *compptr, 445 JSAMPARRAY input_data, 446 JSAMPARRAY *output_data_ptr) 447 { 448 } 449 450 GLOBAL(void) 451 jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo, 452 jpeg_component_info *compptr, 453 JSAMPARRAY input_data, 454 JSAMPARRAY *output_data_ptr) 455 { 456 } 457 458 GLOBAL(int) 459 jsimd_can_h2v2_merged_upsample (void) 460 { 461 init_simd(); 462 463 return 0; 464 } 465 466 GLOBAL(int) 467 jsimd_can_h2v1_merged_upsample (void) 468 { 469 init_simd(); 470 471 return 0; 472 } 473 474 GLOBAL(void) 475 jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo, 476 JSAMPIMAGE input_buf, 477 JDIMENSION in_row_group_ctr, 478 JSAMPARRAY output_buf) 479 { 480 } 481 482 GLOBAL(void) 483 jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo, 484 JSAMPIMAGE input_buf, 485 JDIMENSION in_row_group_ctr, 486 JSAMPARRAY output_buf) 487 { 488 } 489 490 GLOBAL(int) 491 jsimd_can_convsamp (void) 492 { 493 init_simd(); 494 495 /* The code is optimised for these values only */ 496 if (DCTSIZE != 8) 497 return 0; 498 if (BITS_IN_JSAMPLE != 8) 499 return 0; 500 if (sizeof(JDIMENSION) != 4) 501 return 0; 502 if (sizeof(DCTELEM) != 2) 503 return 0; 504 505 if (simd_support & JSIMD_ARM_NEON) 506 return 1; 507 508 return 0; 509 } 510 511 GLOBAL(int) 512 jsimd_can_convsamp_float (void) 513 { 514 init_simd(); 515 516 return 0; 517 } 518 519 GLOBAL(void) 520 jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, 521 DCTELEM *workspace) 522 { 523 jsimd_convsamp_neon(sample_data, start_col, workspace); 524 } 525 526 GLOBAL(void) 527 jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, 528 FAST_FLOAT *workspace) 529 { 530 } 531 532 GLOBAL(int) 533 jsimd_can_fdct_islow (void) 534 { 535 init_simd(); 536 537 /* The code is optimised for these values only */ 538 if (DCTSIZE != 8) 539 return 0; 540 if (sizeof(DCTELEM) != 2) 541 return 0; 542 543 if (simd_support & JSIMD_ARM_NEON) 544 return 1; 545 546 return 0; 547 } 548 549 GLOBAL(int) 550 jsimd_can_fdct_ifast (void) 551 { 552 init_simd(); 553 554 /* The code is optimised for these values only */ 555 if (DCTSIZE != 8) 556 return 0; 557 if (sizeof(DCTELEM) != 2) 558 return 0; 559 560 if (simd_support & JSIMD_ARM_NEON) 561 return 1; 562 563 return 0; 564 } 565 566 GLOBAL(int) 567 jsimd_can_fdct_float (void) 568 { 569 init_simd(); 570 571 return 0; 572 } 573 574 GLOBAL(void) 575 jsimd_fdct_islow (DCTELEM *data) 576 { 577 jsimd_fdct_islow_neon(data); 578 } 579 580 GLOBAL(void) 581 jsimd_fdct_ifast (DCTELEM *data) 582 { 583 jsimd_fdct_ifast_neon(data); 584 } 585 586 GLOBAL(void) 587 jsimd_fdct_float (FAST_FLOAT *data) 588 { 589 } 590 591 GLOBAL(int) 592 jsimd_can_quantize (void) 593 { 594 init_simd(); 595 596 /* The code is optimised for these values only */ 597 if (DCTSIZE != 8) 598 return 0; 599 if (sizeof(JCOEF) != 2) 600 return 0; 601 if (sizeof(DCTELEM) != 2) 602 return 0; 603 604 if (simd_support & JSIMD_ARM_NEON) 605 return 1; 606 607 return 0; 608 } 609 610 GLOBAL(int) 611 jsimd_can_quantize_float (void) 612 { 613 init_simd(); 614 615 return 0; 616 } 617 618 GLOBAL(void) 619 jsimd_quantize (JCOEFPTR coef_block, DCTELEM *divisors, 620 DCTELEM *workspace) 621 { 622 jsimd_quantize_neon(coef_block, divisors, workspace); 623 } 624 625 GLOBAL(void) 626 jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT *divisors, 627 FAST_FLOAT *workspace) 628 { 629 } 630 631 GLOBAL(int) 632 jsimd_can_idct_2x2 (void) 633 { 634 init_simd(); 635 636 /* The code is optimised for these values only */ 637 if (DCTSIZE != 8) 638 return 0; 639 if (sizeof(JCOEF) != 2) 640 return 0; 641 if (BITS_IN_JSAMPLE != 8) 642 return 0; 643 if (sizeof(JDIMENSION) != 4) 644 return 0; 645 if (sizeof(ISLOW_MULT_TYPE) != 2) 646 return 0; 647 648 if (simd_support & JSIMD_ARM_NEON) 649 return 1; 650 651 return 0; 652 } 653 654 GLOBAL(int) 655 jsimd_can_idct_4x4 (void) 656 { 657 init_simd(); 658 659 /* The code is optimised for these values only */ 660 if (DCTSIZE != 8) 661 return 0; 662 if (sizeof(JCOEF) != 2) 663 return 0; 664 if (BITS_IN_JSAMPLE != 8) 665 return 0; 666 if (sizeof(JDIMENSION) != 4) 667 return 0; 668 if (sizeof(ISLOW_MULT_TYPE) != 2) 669 return 0; 670 671 if (simd_support & JSIMD_ARM_NEON) 672 return 1; 673 674 return 0; 675 } 676 677 GLOBAL(void) 678 jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info *compptr, 679 JCOEFPTR coef_block, JSAMPARRAY output_buf, 680 JDIMENSION output_col) 681 { 682 jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, 683 output_col); 684 } 685 686 GLOBAL(void) 687 jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info *compptr, 688 JCOEFPTR coef_block, JSAMPARRAY output_buf, 689 JDIMENSION output_col) 690 { 691 jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, 692 output_col); 693 } 694 695 GLOBAL(int) 696 jsimd_can_idct_islow (void) 697 { 698 init_simd(); 699 700 /* The code is optimised for these values only */ 701 if (DCTSIZE != 8) 702 return 0; 703 if (sizeof(JCOEF) != 2) 704 return 0; 705 if (BITS_IN_JSAMPLE != 8) 706 return 0; 707 if (sizeof(JDIMENSION) != 4) 708 return 0; 709 if (sizeof(ISLOW_MULT_TYPE) != 2) 710 return 0; 711 712 if (simd_support & JSIMD_ARM_NEON) 713 return 1; 714 715 return 0; 716 } 717 718 GLOBAL(int) 719 jsimd_can_idct_ifast (void) 720 { 721 init_simd(); 722 723 /* The code is optimised for these values only */ 724 if (DCTSIZE != 8) 725 return 0; 726 if (sizeof(JCOEF) != 2) 727 return 0; 728 if (BITS_IN_JSAMPLE != 8) 729 return 0; 730 if (sizeof(JDIMENSION) != 4) 731 return 0; 732 if (sizeof(IFAST_MULT_TYPE) != 2) 733 return 0; 734 if (IFAST_SCALE_BITS != 2) 735 return 0; 736 737 if (simd_support & JSIMD_ARM_NEON) 738 return 1; 739 740 return 0; 741 } 742 743 GLOBAL(int) 744 jsimd_can_idct_float (void) 745 { 746 init_simd(); 747 748 return 0; 749 } 750 751 GLOBAL(void) 752 jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info *compptr, 753 JCOEFPTR coef_block, JSAMPARRAY output_buf, 754 JDIMENSION output_col) 755 { 756 jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf, 757 output_col); 758 } 759 760 GLOBAL(void) 761 jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info *compptr, 762 JCOEFPTR coef_block, JSAMPARRAY output_buf, 763 JDIMENSION output_col) 764 { 765 jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf, 766 output_col); 767 } 768 769 GLOBAL(void) 770 jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info *compptr, 771 JCOEFPTR coef_block, JSAMPARRAY output_buf, 772 JDIMENSION output_col) 773 { 774 } 775 776 GLOBAL(int) 777 jsimd_can_huff_encode_one_block (void) 778 { 779 init_simd(); 780 781 if (DCTSIZE != 8) 782 return 0; 783 if (sizeof(JCOEF) != 2) 784 return 0; 785 786 if (simd_support & JSIMD_ARM_NEON && simd_huffman) 787 return 1; 788 789 return 0; 790 } 791 792 GLOBAL(JOCTET*) 793 jsimd_huff_encode_one_block (void *state, JOCTET *buffer, JCOEFPTR block, 794 int last_dc_val, c_derived_tbl *dctbl, 795 c_derived_tbl *actbl) 796 { 797 if (simd_features & JSIMD_FASTTBL) 798 return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val, 799 dctbl, actbl); 800 else 801 return jsimd_huff_encode_one_block_neon_slowtbl(state, buffer, block, 802 last_dc_val, dctbl, actbl); 803 } 804