tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }