jsimd.c (21898B)
1 /* 2 * jsimd_arm.c 3 * 4 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB 5 * Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies). 6 * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2022, D. R. Commander. 7 * Copyright (C) 2015-2016, 2018, 2022, Matthieu Darbois. 8 * Copyright (C) 2019, Google LLC. 9 * Copyright (C) 2020, Arm Limited. 10 * 11 * Based on the x86 SIMD extension for IJG JPEG library, 12 * Copyright (C) 1999-2006, MIYASAKA Masaru. 13 * For conditions of distribution and use, see copyright notice in jsimdext.inc 14 * 15 * This file contains the interface between the "normal" portions 16 * of the library and the SIMD implementations when running on a 17 * 32-bit Arm architecture. 18 */ 19 20 #define JPEG_INTERNALS 21 #include "../../../jinclude.h" 22 #include "../../../jpeglib.h" 23 #include "../../../jsimd.h" 24 #include "../../../jdct.h" 25 #include "../../../jsimddct.h" 26 #include "../../jsimd.h" 27 28 #include <ctype.h> 29 30 static THREAD_LOCAL unsigned int simd_support = ~0; 31 static THREAD_LOCAL unsigned int simd_huffman = 1; 32 33 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)) 34 35 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024) 36 37 LOCAL(int) 38 check_feature(char *buffer, char *feature) 39 { 40 char *p; 41 42 if (*feature == 0) 43 return 0; 44 if (strncmp(buffer, "Features", 8) != 0) 45 return 0; 46 buffer += 8; 47 while (isspace(*buffer)) 48 buffer++; 49 50 /* Check if 'feature' is present in the buffer as a separate word */ 51 while ((p = strstr(buffer, feature))) { 52 if (p > buffer && !isspace(*(p - 1))) { 53 buffer++; 54 continue; 55 } 56 p += strlen(feature); 57 if (*p != 0 && !isspace(*p)) { 58 buffer++; 59 continue; 60 } 61 return 1; 62 } 63 return 0; 64 } 65 66 LOCAL(int) 67 parse_proc_cpuinfo(int bufsize) 68 { 69 char *buffer = (char *)malloc(bufsize); 70 FILE *fd; 71 72 simd_support = 0; 73 74 if (!buffer) 75 return 0; 76 77 fd = fopen("/proc/cpuinfo", "r"); 78 if (fd) { 79 while (fgets(buffer, bufsize, fd)) { 80 if (!strchr(buffer, '\n') && !feof(fd)) { 81 /* "impossible" happened - insufficient size of the buffer! */ 82 fclose(fd); 83 free(buffer); 84 return 0; 85 } 86 if (check_feature(buffer, "neon")) 87 simd_support |= JSIMD_NEON; 88 } 89 fclose(fd); 90 } 91 free(buffer); 92 return 1; 93 } 94 95 #endif 96 97 /* 98 * Check what SIMD accelerations are supported. 99 */ 100 LOCAL(void) 101 init_simd(void) 102 { 103 #ifndef NO_GETENV 104 char env[2] = { 0 }; 105 #endif 106 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)) 107 int bufsize = 1024; /* an initial guess for the line buffer size limit */ 108 #endif 109 110 if (simd_support != ~0U) 111 return; 112 113 simd_support = 0; 114 115 #if defined(__ARM_NEON__) 116 simd_support |= JSIMD_NEON; 117 #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__) 118 /* We still have a chance to use Neon regardless of globally used 119 * -mcpu/-mfpu options passed to gcc by performing runtime detection via 120 * /proc/cpuinfo parsing on linux/android */ 121 while (!parse_proc_cpuinfo(bufsize)) { 122 bufsize *= 2; 123 if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT) 124 break; 125 } 126 #endif 127 128 #ifndef NO_GETENV 129 /* Force different settings through environment variables */ 130 if (!GETENV_S(env, 2, "JSIMD_FORCENEON") && !strcmp(env, "1")) 131 simd_support = JSIMD_NEON; 132 if (!GETENV_S(env, 2, "JSIMD_FORCENONE") && !strcmp(env, "1")) 133 simd_support = 0; 134 if (!GETENV_S(env, 2, "JSIMD_NOHUFFENC") && !strcmp(env, "1")) 135 simd_huffman = 0; 136 #endif 137 } 138 139 GLOBAL(int) 140 jsimd_can_rgb_ycc(void) 141 { 142 init_simd(); 143 144 /* The code is optimised for these values only */ 145 if (BITS_IN_JSAMPLE != 8) 146 return 0; 147 if (sizeof(JDIMENSION) != 4) 148 return 0; 149 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4)) 150 return 0; 151 152 if (simd_support & JSIMD_NEON) 153 return 1; 154 155 return 0; 156 } 157 158 GLOBAL(int) 159 jsimd_can_rgb_gray(void) 160 { 161 init_simd(); 162 163 /* The code is optimised for these values only */ 164 if (BITS_IN_JSAMPLE != 8) 165 return 0; 166 if (sizeof(JDIMENSION) != 4) 167 return 0; 168 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4)) 169 return 0; 170 171 if (simd_support & JSIMD_NEON) 172 return 1; 173 174 return 0; 175 } 176 177 GLOBAL(int) 178 jsimd_can_ycc_rgb(void) 179 { 180 init_simd(); 181 182 /* The code is optimised for these values only */ 183 if (BITS_IN_JSAMPLE != 8) 184 return 0; 185 if (sizeof(JDIMENSION) != 4) 186 return 0; 187 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4)) 188 return 0; 189 190 if (simd_support & JSIMD_NEON) 191 return 1; 192 193 return 0; 194 } 195 196 GLOBAL(int) 197 jsimd_can_ycc_rgb565(void) 198 { 199 init_simd(); 200 201 /* The code is optimised for these values only */ 202 if (BITS_IN_JSAMPLE != 8) 203 return 0; 204 if (sizeof(JDIMENSION) != 4) 205 return 0; 206 207 if (simd_support & JSIMD_NEON) 208 return 1; 209 210 return 0; 211 } 212 213 GLOBAL(void) 214 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, 215 JSAMPIMAGE output_buf, JDIMENSION output_row, 216 int num_rows) 217 { 218 void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int); 219 220 switch (cinfo->in_color_space) { 221 case JCS_EXT_RGB: 222 neonfct = jsimd_extrgb_ycc_convert_neon; 223 break; 224 case JCS_EXT_RGBX: 225 case JCS_EXT_RGBA: 226 neonfct = jsimd_extrgbx_ycc_convert_neon; 227 break; 228 case JCS_EXT_BGR: 229 neonfct = jsimd_extbgr_ycc_convert_neon; 230 break; 231 case JCS_EXT_BGRX: 232 case JCS_EXT_BGRA: 233 neonfct = jsimd_extbgrx_ycc_convert_neon; 234 break; 235 case JCS_EXT_XBGR: 236 case JCS_EXT_ABGR: 237 neonfct = jsimd_extxbgr_ycc_convert_neon; 238 break; 239 case JCS_EXT_XRGB: 240 case JCS_EXT_ARGB: 241 neonfct = jsimd_extxrgb_ycc_convert_neon; 242 break; 243 default: 244 neonfct = jsimd_extrgb_ycc_convert_neon; 245 break; 246 } 247 248 neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows); 249 } 250 251 GLOBAL(void) 252 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf, 253 JSAMPIMAGE output_buf, JDIMENSION output_row, 254 int num_rows) 255 { 256 void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int); 257 258 switch (cinfo->in_color_space) { 259 case JCS_EXT_RGB: 260 neonfct = jsimd_extrgb_gray_convert_neon; 261 break; 262 case JCS_EXT_RGBX: 263 case JCS_EXT_RGBA: 264 neonfct = jsimd_extrgbx_gray_convert_neon; 265 break; 266 case JCS_EXT_BGR: 267 neonfct = jsimd_extbgr_gray_convert_neon; 268 break; 269 case JCS_EXT_BGRX: 270 case JCS_EXT_BGRA: 271 neonfct = jsimd_extbgrx_gray_convert_neon; 272 break; 273 case JCS_EXT_XBGR: 274 case JCS_EXT_ABGR: 275 neonfct = jsimd_extxbgr_gray_convert_neon; 276 break; 277 case JCS_EXT_XRGB: 278 case JCS_EXT_ARGB: 279 neonfct = jsimd_extxrgb_gray_convert_neon; 280 break; 281 default: 282 neonfct = jsimd_extrgb_gray_convert_neon; 283 break; 284 } 285 286 neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows); 287 } 288 289 GLOBAL(void) 290 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 291 JDIMENSION input_row, JSAMPARRAY output_buf, 292 int num_rows) 293 { 294 void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int); 295 296 switch (cinfo->out_color_space) { 297 case JCS_EXT_RGB: 298 neonfct = jsimd_ycc_extrgb_convert_neon; 299 break; 300 case JCS_EXT_RGBX: 301 case JCS_EXT_RGBA: 302 neonfct = jsimd_ycc_extrgbx_convert_neon; 303 break; 304 case JCS_EXT_BGR: 305 neonfct = jsimd_ycc_extbgr_convert_neon; 306 break; 307 case JCS_EXT_BGRX: 308 case JCS_EXT_BGRA: 309 neonfct = jsimd_ycc_extbgrx_convert_neon; 310 break; 311 case JCS_EXT_XBGR: 312 case JCS_EXT_ABGR: 313 neonfct = jsimd_ycc_extxbgr_convert_neon; 314 break; 315 case JCS_EXT_XRGB: 316 case JCS_EXT_ARGB: 317 neonfct = jsimd_ycc_extxrgb_convert_neon; 318 break; 319 default: 320 neonfct = jsimd_ycc_extrgb_convert_neon; 321 break; 322 } 323 324 neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows); 325 } 326 327 GLOBAL(void) 328 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 329 JDIMENSION input_row, JSAMPARRAY output_buf, 330 int num_rows) 331 { 332 jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row, 333 output_buf, num_rows); 334 } 335 336 GLOBAL(int) 337 jsimd_can_h2v2_downsample(void) 338 { 339 init_simd(); 340 341 /* The code is optimised for these values only */ 342 if (BITS_IN_JSAMPLE != 8) 343 return 0; 344 if (DCTSIZE != 8) 345 return 0; 346 if (sizeof(JDIMENSION) != 4) 347 return 0; 348 349 if (simd_support & JSIMD_NEON) 350 return 1; 351 352 return 0; 353 } 354 355 GLOBAL(int) 356 jsimd_can_h2v1_downsample(void) 357 { 358 init_simd(); 359 360 /* The code is optimised for these values only */ 361 if (BITS_IN_JSAMPLE != 8) 362 return 0; 363 if (DCTSIZE != 8) 364 return 0; 365 if (sizeof(JDIMENSION) != 4) 366 return 0; 367 368 if (simd_support & JSIMD_NEON) 369 return 1; 370 371 return 0; 372 } 373 374 GLOBAL(void) 375 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, 376 JSAMPARRAY input_data, JSAMPARRAY output_data) 377 { 378 jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor, 379 compptr->v_samp_factor, compptr->width_in_blocks, 380 input_data, output_data); 381 } 382 383 GLOBAL(void) 384 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr, 385 JSAMPARRAY input_data, JSAMPARRAY output_data) 386 { 387 jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor, 388 compptr->v_samp_factor, compptr->width_in_blocks, 389 input_data, output_data); 390 } 391 392 GLOBAL(int) 393 jsimd_can_h2v2_upsample(void) 394 { 395 init_simd(); 396 397 /* The code is optimised for these values only */ 398 if (BITS_IN_JSAMPLE != 8) 399 return 0; 400 if (sizeof(JDIMENSION) != 4) 401 return 0; 402 403 if (simd_support & JSIMD_NEON) 404 return 1; 405 406 return 0; 407 } 408 409 GLOBAL(int) 410 jsimd_can_h2v1_upsample(void) 411 { 412 init_simd(); 413 414 /* The code is optimised for these values only */ 415 if (BITS_IN_JSAMPLE != 8) 416 return 0; 417 if (sizeof(JDIMENSION) != 4) 418 return 0; 419 if (simd_support & JSIMD_NEON) 420 return 1; 421 422 return 0; 423 } 424 425 GLOBAL(void) 426 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, 427 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) 428 { 429 jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width, 430 input_data, output_data_ptr); 431 } 432 433 GLOBAL(void) 434 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, 435 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) 436 { 437 jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width, 438 input_data, output_data_ptr); 439 } 440 441 GLOBAL(int) 442 jsimd_can_h2v2_fancy_upsample(void) 443 { 444 init_simd(); 445 446 /* The code is optimised for these values only */ 447 if (BITS_IN_JSAMPLE != 8) 448 return 0; 449 if (sizeof(JDIMENSION) != 4) 450 return 0; 451 452 if (simd_support & JSIMD_NEON) 453 return 1; 454 455 return 0; 456 } 457 458 GLOBAL(int) 459 jsimd_can_h2v1_fancy_upsample(void) 460 { 461 init_simd(); 462 463 /* The code is optimised for these values only */ 464 if (BITS_IN_JSAMPLE != 8) 465 return 0; 466 if (sizeof(JDIMENSION) != 4) 467 return 0; 468 469 if (simd_support & JSIMD_NEON) 470 return 1; 471 472 return 0; 473 } 474 475 GLOBAL(int) 476 jsimd_can_h1v2_fancy_upsample(void) 477 { 478 init_simd(); 479 480 /* The code is optimised for these values only */ 481 if (BITS_IN_JSAMPLE != 8) 482 return 0; 483 if (sizeof(JDIMENSION) != 4) 484 return 0; 485 486 if (simd_support & JSIMD_NEON) 487 return 1; 488 489 return 0; 490 } 491 492 GLOBAL(void) 493 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, 494 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) 495 { 496 jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor, 497 compptr->downsampled_width, input_data, 498 output_data_ptr); 499 } 500 501 GLOBAL(void) 502 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, 503 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) 504 { 505 jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor, 506 compptr->downsampled_width, input_data, 507 output_data_ptr); 508 } 509 510 GLOBAL(void) 511 jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr, 512 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr) 513 { 514 jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor, 515 compptr->downsampled_width, input_data, 516 output_data_ptr); 517 } 518 519 GLOBAL(int) 520 jsimd_can_h2v2_merged_upsample(void) 521 { 522 init_simd(); 523 524 /* The code is optimised for these values only */ 525 if (BITS_IN_JSAMPLE != 8) 526 return 0; 527 if (sizeof(JDIMENSION) != 4) 528 return 0; 529 530 if (simd_support & JSIMD_NEON) 531 return 1; 532 533 return 0; 534 } 535 536 GLOBAL(int) 537 jsimd_can_h2v1_merged_upsample(void) 538 { 539 init_simd(); 540 541 /* The code is optimised for these values only */ 542 if (BITS_IN_JSAMPLE != 8) 543 return 0; 544 if (sizeof(JDIMENSION) != 4) 545 return 0; 546 547 if (simd_support & JSIMD_NEON) 548 return 1; 549 550 return 0; 551 } 552 553 GLOBAL(void) 554 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 555 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf) 556 { 557 void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY); 558 559 switch (cinfo->out_color_space) { 560 case JCS_EXT_RGB: 561 neonfct = jsimd_h2v2_extrgb_merged_upsample_neon; 562 break; 563 case JCS_EXT_RGBX: 564 case JCS_EXT_RGBA: 565 neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon; 566 break; 567 case JCS_EXT_BGR: 568 neonfct = jsimd_h2v2_extbgr_merged_upsample_neon; 569 break; 570 case JCS_EXT_BGRX: 571 case JCS_EXT_BGRA: 572 neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon; 573 break; 574 case JCS_EXT_XBGR: 575 case JCS_EXT_ABGR: 576 neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon; 577 break; 578 case JCS_EXT_XRGB: 579 case JCS_EXT_ARGB: 580 neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon; 581 break; 582 default: 583 neonfct = jsimd_h2v2_extrgb_merged_upsample_neon; 584 break; 585 } 586 587 neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf); 588 } 589 590 GLOBAL(void) 591 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 592 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf) 593 { 594 void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY); 595 596 switch (cinfo->out_color_space) { 597 case JCS_EXT_RGB: 598 neonfct = jsimd_h2v1_extrgb_merged_upsample_neon; 599 break; 600 case JCS_EXT_RGBX: 601 case JCS_EXT_RGBA: 602 neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon; 603 break; 604 case JCS_EXT_BGR: 605 neonfct = jsimd_h2v1_extbgr_merged_upsample_neon; 606 break; 607 case JCS_EXT_BGRX: 608 case JCS_EXT_BGRA: 609 neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon; 610 break; 611 case JCS_EXT_XBGR: 612 case JCS_EXT_ABGR: 613 neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon; 614 break; 615 case JCS_EXT_XRGB: 616 case JCS_EXT_ARGB: 617 neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon; 618 break; 619 default: 620 neonfct = jsimd_h2v1_extrgb_merged_upsample_neon; 621 break; 622 } 623 624 neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf); 625 } 626 627 GLOBAL(int) 628 jsimd_can_convsamp(void) 629 { 630 init_simd(); 631 632 /* The code is optimised for these values only */ 633 if (DCTSIZE != 8) 634 return 0; 635 if (BITS_IN_JSAMPLE != 8) 636 return 0; 637 if (sizeof(JDIMENSION) != 4) 638 return 0; 639 if (sizeof(DCTELEM) != 2) 640 return 0; 641 642 if (simd_support & JSIMD_NEON) 643 return 1; 644 645 return 0; 646 } 647 648 GLOBAL(int) 649 jsimd_can_convsamp_float(void) 650 { 651 return 0; 652 } 653 654 GLOBAL(void) 655 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col, 656 DCTELEM *workspace) 657 { 658 jsimd_convsamp_neon(sample_data, start_col, workspace); 659 } 660 661 GLOBAL(void) 662 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col, 663 FAST_FLOAT *workspace) 664 { 665 } 666 667 GLOBAL(int) 668 jsimd_can_fdct_islow(void) 669 { 670 init_simd(); 671 672 /* The code is optimised for these values only */ 673 if (DCTSIZE != 8) 674 return 0; 675 if (sizeof(DCTELEM) != 2) 676 return 0; 677 678 if (simd_support & JSIMD_NEON) 679 return 1; 680 681 return 0; 682 } 683 684 GLOBAL(int) 685 jsimd_can_fdct_ifast(void) 686 { 687 init_simd(); 688 689 /* The code is optimised for these values only */ 690 if (DCTSIZE != 8) 691 return 0; 692 if (sizeof(DCTELEM) != 2) 693 return 0; 694 695 if (simd_support & JSIMD_NEON) 696 return 1; 697 698 return 0; 699 } 700 701 GLOBAL(int) 702 jsimd_can_fdct_float(void) 703 { 704 return 0; 705 } 706 707 GLOBAL(void) 708 jsimd_fdct_islow(DCTELEM *data) 709 { 710 jsimd_fdct_islow_neon(data); 711 } 712 713 GLOBAL(void) 714 jsimd_fdct_ifast(DCTELEM *data) 715 { 716 jsimd_fdct_ifast_neon(data); 717 } 718 719 GLOBAL(void) 720 jsimd_fdct_float(FAST_FLOAT *data) 721 { 722 } 723 724 GLOBAL(int) 725 jsimd_can_quantize(void) 726 { 727 init_simd(); 728 729 /* The code is optimised for these values only */ 730 if (DCTSIZE != 8) 731 return 0; 732 if (sizeof(JCOEF) != 2) 733 return 0; 734 if (sizeof(DCTELEM) != 2) 735 return 0; 736 737 if (simd_support & JSIMD_NEON) 738 return 1; 739 740 return 0; 741 } 742 743 GLOBAL(int) 744 jsimd_can_quantize_float(void) 745 { 746 return 0; 747 } 748 749 GLOBAL(void) 750 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace) 751 { 752 jsimd_quantize_neon(coef_block, divisors, workspace); 753 } 754 755 GLOBAL(void) 756 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors, 757 FAST_FLOAT *workspace) 758 { 759 } 760 761 GLOBAL(int) 762 jsimd_can_idct_2x2(void) 763 { 764 init_simd(); 765 766 /* The code is optimised for these values only */ 767 if (DCTSIZE != 8) 768 return 0; 769 if (sizeof(JCOEF) != 2) 770 return 0; 771 if (BITS_IN_JSAMPLE != 8) 772 return 0; 773 if (sizeof(JDIMENSION) != 4) 774 return 0; 775 if (sizeof(ISLOW_MULT_TYPE) != 2) 776 return 0; 777 778 if (simd_support & JSIMD_NEON) 779 return 1; 780 781 return 0; 782 } 783 784 GLOBAL(int) 785 jsimd_can_idct_4x4(void) 786 { 787 init_simd(); 788 789 /* The code is optimised for these values only */ 790 if (DCTSIZE != 8) 791 return 0; 792 if (sizeof(JCOEF) != 2) 793 return 0; 794 if (BITS_IN_JSAMPLE != 8) 795 return 0; 796 if (sizeof(JDIMENSION) != 4) 797 return 0; 798 if (sizeof(ISLOW_MULT_TYPE) != 2) 799 return 0; 800 801 if (simd_support & JSIMD_NEON) 802 return 1; 803 804 return 0; 805 } 806 807 GLOBAL(void) 808 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr, 809 JCOEFPTR coef_block, JSAMPARRAY output_buf, 810 JDIMENSION output_col) 811 { 812 jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col); 813 } 814 815 GLOBAL(void) 816 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr, 817 JCOEFPTR coef_block, JSAMPARRAY output_buf, 818 JDIMENSION output_col) 819 { 820 jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col); 821 } 822 823 GLOBAL(int) 824 jsimd_can_idct_islow(void) 825 { 826 init_simd(); 827 828 /* The code is optimised for these values only */ 829 if (DCTSIZE != 8) 830 return 0; 831 if (sizeof(JCOEF) != 2) 832 return 0; 833 if (BITS_IN_JSAMPLE != 8) 834 return 0; 835 if (sizeof(JDIMENSION) != 4) 836 return 0; 837 if (sizeof(ISLOW_MULT_TYPE) != 2) 838 return 0; 839 840 if (simd_support & JSIMD_NEON) 841 return 1; 842 843 return 0; 844 } 845 846 GLOBAL(int) 847 jsimd_can_idct_ifast(void) 848 { 849 init_simd(); 850 851 /* The code is optimised for these values only */ 852 if (DCTSIZE != 8) 853 return 0; 854 if (sizeof(JCOEF) != 2) 855 return 0; 856 if (BITS_IN_JSAMPLE != 8) 857 return 0; 858 if (sizeof(JDIMENSION) != 4) 859 return 0; 860 if (sizeof(IFAST_MULT_TYPE) != 2) 861 return 0; 862 if (IFAST_SCALE_BITS != 2) 863 return 0; 864 865 if (simd_support & JSIMD_NEON) 866 return 1; 867 868 return 0; 869 } 870 871 GLOBAL(int) 872 jsimd_can_idct_float(void) 873 { 874 return 0; 875 } 876 877 GLOBAL(void) 878 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr, 879 JCOEFPTR coef_block, JSAMPARRAY output_buf, 880 JDIMENSION output_col) 881 { 882 jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf, 883 output_col); 884 } 885 886 GLOBAL(void) 887 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr, 888 JCOEFPTR coef_block, JSAMPARRAY output_buf, 889 JDIMENSION output_col) 890 { 891 jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf, 892 output_col); 893 } 894 895 GLOBAL(void) 896 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr, 897 JCOEFPTR coef_block, JSAMPARRAY output_buf, 898 JDIMENSION output_col) 899 { 900 } 901 902 GLOBAL(int) 903 jsimd_can_huff_encode_one_block(void) 904 { 905 init_simd(); 906 907 if (DCTSIZE != 8) 908 return 0; 909 if (sizeof(JCOEF) != 2) 910 return 0; 911 912 if (simd_support & JSIMD_NEON && simd_huffman) 913 return 1; 914 915 return 0; 916 } 917 918 GLOBAL(JOCTET *) 919 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block, 920 int last_dc_val, c_derived_tbl *dctbl, 921 c_derived_tbl *actbl) 922 { 923 return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val, 924 dctbl, actbl); 925 } 926 927 GLOBAL(int) 928 jsimd_can_encode_mcu_AC_first_prepare(void) 929 { 930 init_simd(); 931 932 if (DCTSIZE != 8) 933 return 0; 934 if (sizeof(JCOEF) != 2) 935 return 0; 936 937 if (simd_support & JSIMD_NEON) 938 return 1; 939 940 return 0; 941 } 942 943 GLOBAL(void) 944 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block, 945 const int *jpeg_natural_order_start, int Sl, 946 int Al, UJCOEF *values, size_t *zerobits) 947 { 948 jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start, 949 Sl, Al, values, zerobits); 950 } 951 952 GLOBAL(int) 953 jsimd_can_encode_mcu_AC_refine_prepare(void) 954 { 955 init_simd(); 956 957 if (DCTSIZE != 8) 958 return 0; 959 if (sizeof(JCOEF) != 2) 960 return 0; 961 962 if (simd_support & JSIMD_NEON) 963 return 1; 964 965 return 0; 966 } 967 968 GLOBAL(int) 969 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block, 970 const int *jpeg_natural_order_start, int Sl, 971 int Al, UJCOEF *absvalues, size_t *bits) 972 { 973 return jsimd_encode_mcu_AC_refine_prepare_neon(block, 974 jpeg_natural_order_start, Sl, 975 Al, absvalues, bits); 976 }