tor-browser

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

jsimd.c (26489B)


      1 /*
      2 * jsimd_mips.c
      3 *
      4 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
      5 * Copyright (C) 2009-2011, 2014, 2016, 2018, 2020, 2022, D. R. Commander.
      6 * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
      7 * Copyright (C) 2015-2016, 2018, 2022, 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 * MIPS 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 <ctype.h>
     27 
     28 static THREAD_LOCAL unsigned int simd_support = ~0;
     29 
     30 #if !(defined(__mips_dsp) && (__mips_dsp_rev >= 2)) && defined(__linux__)
     31 
     32 LOCAL(void)
     33 parse_proc_cpuinfo(const char *search_string)
     34 {
     35  const char *file_name = "/proc/cpuinfo";
     36  char cpuinfo_line[256];
     37  FILE *f = NULL;
     38 
     39  simd_support = 0;
     40 
     41  if ((f = fopen(file_name, "r")) != NULL) {
     42    while (fgets(cpuinfo_line, sizeof(cpuinfo_line), f) != NULL) {
     43      if (strstr(cpuinfo_line, search_string) != NULL) {
     44        fclose(f);
     45        simd_support |= JSIMD_DSPR2;
     46        return;
     47      }
     48    }
     49    fclose(f);
     50  }
     51  /* Did not find string in the proc file, or not Linux ELF. */
     52 }
     53 
     54 #endif
     55 
     56 /*
     57 * Check what SIMD accelerations are supported.
     58 */
     59 LOCAL(void)
     60 init_simd(void)
     61 {
     62 #ifndef NO_GETENV
     63  char *env = NULL;
     64 #endif
     65 
     66  if (simd_support != ~0U)
     67    return;
     68 
     69  simd_support = 0;
     70 
     71 #if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
     72  simd_support |= JSIMD_DSPR2;
     73 #elif defined(__linux__)
     74  /* We still have a chance to use MIPS DSPR2 regardless of globally used
     75   * -mdspr2 options passed to gcc by performing runtime detection via
     76   * /proc/cpuinfo parsing on linux */
     77  parse_proc_cpuinfo("MIPS 74K");
     78 #endif
     79 
     80 #ifndef NO_GETENV
     81  /* Force different settings through environment variables */
     82  env = getenv("JSIMD_FORCEDSPR2");
     83  if ((env != NULL) && (strcmp(env, "1") == 0))
     84    simd_support = JSIMD_DSPR2;
     85  env = getenv("JSIMD_FORCENONE");
     86  if ((env != NULL) && (strcmp(env, "1") == 0))
     87    simd_support = 0;
     88 #endif
     89 }
     90 
     91 static const int mips_idct_ifast_coefs[4] = {
     92  0x45404540,           /* FIX( 1.082392200 / 2) =  17734 = 0x4546 */
     93  0x5A805A80,           /* FIX( 1.414213562 / 2) =  23170 = 0x5A82 */
     94  0x76407640,           /* FIX( 1.847759065 / 2) =  30274 = 0x7642 */
     95  0xAC60AC60            /* FIX(-2.613125930 / 4) = -21407 = 0xAC61 */
     96 };
     97 
     98 /* The following struct is borrowed from jdsample.c */
     99 typedef void (*upsample1_ptr) (j_decompress_ptr cinfo,
    100                               jpeg_component_info *compptr,
    101                               JSAMPARRAY input_data,
    102                               JSAMPARRAY *output_data_ptr);
    103 typedef struct {
    104  struct jpeg_upsampler pub;
    105  JSAMPARRAY color_buf[MAX_COMPONENTS];
    106  upsample1_ptr methods[MAX_COMPONENTS];
    107  int next_row_out;
    108  JDIMENSION rows_to_go;
    109  int rowgroup_height[MAX_COMPONENTS];
    110  UINT8 h_expand[MAX_COMPONENTS];
    111  UINT8 v_expand[MAX_COMPONENTS];
    112 } my_upsampler;
    113 
    114 typedef my_upsampler *my_upsample_ptr;
    115 
    116 GLOBAL(int)
    117 jsimd_can_rgb_ycc(void)
    118 {
    119  init_simd();
    120 
    121  /* The code is optimised for these values only */
    122  if (BITS_IN_JSAMPLE != 8)
    123    return 0;
    124  if (sizeof(JDIMENSION) != 4)
    125    return 0;
    126  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
    127    return 0;
    128 
    129  if (simd_support & JSIMD_DSPR2)
    130    return 1;
    131 
    132  return 0;
    133 }
    134 
    135 GLOBAL(int)
    136 jsimd_can_rgb_gray(void)
    137 {
    138  init_simd();
    139 
    140  /* The code is optimised for these values only */
    141  if (BITS_IN_JSAMPLE != 8)
    142    return 0;
    143  if (sizeof(JDIMENSION) != 4)
    144    return 0;
    145  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
    146    return 0;
    147 
    148  if (simd_support & JSIMD_DSPR2)
    149    return 1;
    150 
    151  return 0;
    152 }
    153 
    154 GLOBAL(int)
    155 jsimd_can_ycc_rgb(void)
    156 {
    157  init_simd();
    158 
    159  /* The code is optimised for these values only */
    160  if (BITS_IN_JSAMPLE != 8)
    161    return 0;
    162  if (sizeof(JDIMENSION) != 4)
    163    return 0;
    164  if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
    165    return 0;
    166 
    167  if (simd_support & JSIMD_DSPR2)
    168    return 1;
    169 
    170  return 0;
    171 }
    172 
    173 GLOBAL(int)
    174 jsimd_can_ycc_rgb565(void)
    175 {
    176  return 0;
    177 }
    178 
    179 GLOBAL(int)
    180 jsimd_c_can_null_convert(void)
    181 {
    182  init_simd();
    183 
    184  /* The code is optimised for these values only */
    185  if (BITS_IN_JSAMPLE != 8)
    186    return 0;
    187  if (sizeof(JDIMENSION) != 4)
    188    return 0;
    189 
    190  if (simd_support & JSIMD_DSPR2)
    191    return 1;
    192 
    193  return 0;
    194 }
    195 
    196 GLOBAL(void)
    197 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
    198                      JSAMPIMAGE output_buf, JDIMENSION output_row,
    199                      int num_rows)
    200 {
    201  void (*dspr2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
    202 
    203  switch (cinfo->in_color_space) {
    204  case JCS_EXT_RGB:
    205    dspr2fct = jsimd_extrgb_ycc_convert_dspr2;
    206    break;
    207  case JCS_EXT_RGBX:
    208  case JCS_EXT_RGBA:
    209    dspr2fct = jsimd_extrgbx_ycc_convert_dspr2;
    210    break;
    211  case JCS_EXT_BGR:
    212    dspr2fct = jsimd_extbgr_ycc_convert_dspr2;
    213    break;
    214  case JCS_EXT_BGRX:
    215  case JCS_EXT_BGRA:
    216    dspr2fct = jsimd_extbgrx_ycc_convert_dspr2;
    217    break;
    218  case JCS_EXT_XBGR:
    219  case JCS_EXT_ABGR:
    220    dspr2fct = jsimd_extxbgr_ycc_convert_dspr2;
    221    break;
    222  case JCS_EXT_XRGB:
    223  case JCS_EXT_ARGB:
    224    dspr2fct = jsimd_extxrgb_ycc_convert_dspr2;
    225    break;
    226  default:
    227    dspr2fct = jsimd_extrgb_ycc_convert_dspr2;
    228    break;
    229  }
    230 
    231  dspr2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
    232 }
    233 
    234 GLOBAL(void)
    235 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
    236                       JSAMPIMAGE output_buf, JDIMENSION output_row,
    237                       int num_rows)
    238 {
    239  void (*dspr2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
    240 
    241  switch (cinfo->in_color_space) {
    242  case JCS_EXT_RGB:
    243    dspr2fct = jsimd_extrgb_gray_convert_dspr2;
    244    break;
    245  case JCS_EXT_RGBX:
    246  case JCS_EXT_RGBA:
    247    dspr2fct = jsimd_extrgbx_gray_convert_dspr2;
    248    break;
    249  case JCS_EXT_BGR:
    250    dspr2fct = jsimd_extbgr_gray_convert_dspr2;
    251    break;
    252  case JCS_EXT_BGRX:
    253  case JCS_EXT_BGRA:
    254    dspr2fct = jsimd_extbgrx_gray_convert_dspr2;
    255    break;
    256  case JCS_EXT_XBGR:
    257  case JCS_EXT_ABGR:
    258    dspr2fct = jsimd_extxbgr_gray_convert_dspr2;
    259    break;
    260  case JCS_EXT_XRGB:
    261  case JCS_EXT_ARGB:
    262    dspr2fct = jsimd_extxrgb_gray_convert_dspr2;
    263    break;
    264  default:
    265    dspr2fct = jsimd_extrgb_gray_convert_dspr2;
    266    break;
    267  }
    268 
    269  dspr2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
    270 }
    271 
    272 GLOBAL(void)
    273 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    274                      JDIMENSION input_row, JSAMPARRAY output_buf,
    275                      int num_rows)
    276 {
    277  void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
    278 
    279  switch (cinfo->out_color_space) {
    280  case JCS_EXT_RGB:
    281    dspr2fct = jsimd_ycc_extrgb_convert_dspr2;
    282    break;
    283  case JCS_EXT_RGBX:
    284  case JCS_EXT_RGBA:
    285    dspr2fct = jsimd_ycc_extrgbx_convert_dspr2;
    286    break;
    287  case JCS_EXT_BGR:
    288    dspr2fct = jsimd_ycc_extbgr_convert_dspr2;
    289    break;
    290  case JCS_EXT_BGRX:
    291  case JCS_EXT_BGRA:
    292    dspr2fct = jsimd_ycc_extbgrx_convert_dspr2;
    293    break;
    294  case JCS_EXT_XBGR:
    295  case JCS_EXT_ABGR:
    296    dspr2fct = jsimd_ycc_extxbgr_convert_dspr2;
    297    break;
    298  case JCS_EXT_XRGB:
    299  case JCS_EXT_ARGB:
    300    dspr2fct = jsimd_ycc_extxrgb_convert_dspr2;
    301    break;
    302  default:
    303    dspr2fct = jsimd_ycc_extrgb_convert_dspr2;
    304    break;
    305  }
    306 
    307  dspr2fct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
    308 }
    309 
    310 GLOBAL(void)
    311 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    312                         JDIMENSION input_row, JSAMPARRAY output_buf,
    313                         int num_rows)
    314 {
    315 }
    316 
    317 GLOBAL(void)
    318 jsimd_c_null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
    319                     JSAMPIMAGE output_buf, JDIMENSION output_row,
    320                     int num_rows)
    321 {
    322  jsimd_c_null_convert_dspr2(cinfo->image_width, input_buf, output_buf,
    323                             output_row, num_rows, cinfo->num_components);
    324 }
    325 
    326 GLOBAL(int)
    327 jsimd_can_h2v2_downsample(void)
    328 {
    329  init_simd();
    330 
    331  /* The code is optimised for these values only */
    332  if (BITS_IN_JSAMPLE != 8)
    333    return 0;
    334  if (sizeof(JDIMENSION) != 4)
    335    return 0;
    336 
    337  /* FIXME: jsimd_h2v2_downsample_dspr2() fails some of the TJBench tiling
    338   * regression tests, probably because the DSPr2 SIMD implementation predates
    339   * those tests. */
    340 #if 0
    341  if (simd_support & JSIMD_DSPR2)
    342    return 1;
    343 #endif
    344 
    345  return 0;
    346 }
    347 
    348 GLOBAL(int)
    349 jsimd_can_h2v2_smooth_downsample(void)
    350 {
    351  init_simd();
    352 
    353  /* The code is optimised for these values only */
    354  if (BITS_IN_JSAMPLE != 8)
    355    return 0;
    356  if (sizeof(JDIMENSION) != 4)
    357    return 0;
    358  if (DCTSIZE != 8)
    359    return 0;
    360 
    361  if (simd_support & JSIMD_DSPR2)
    362    return 1;
    363 
    364  return 0;
    365 }
    366 
    367 GLOBAL(int)
    368 jsimd_can_h2v1_downsample(void)
    369 {
    370  init_simd();
    371 
    372  /* The code is optimised for these values only */
    373  if (BITS_IN_JSAMPLE != 8)
    374    return 0;
    375  if (sizeof(JDIMENSION) != 4)
    376    return 0;
    377 
    378  /* FIXME: jsimd_h2v1_downsample_dspr2() fails some of the TJBench tiling
    379   * regression tests, probably because the DSPr2 SIMD implementation predates
    380   * those tests. */
    381 #if 0
    382  if (simd_support & JSIMD_DSPR2)
    383    return 1;
    384 #endif
    385 
    386  return 0;
    387 }
    388 
    389 GLOBAL(void)
    390 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
    391                      JSAMPARRAY input_data, JSAMPARRAY output_data)
    392 {
    393  jsimd_h2v2_downsample_dspr2(cinfo->image_width, cinfo->max_v_samp_factor,
    394                              compptr->v_samp_factor, compptr->width_in_blocks,
    395                              input_data, output_data);
    396 }
    397 
    398 GLOBAL(void)
    399 jsimd_h2v2_smooth_downsample(j_compress_ptr cinfo,
    400                             jpeg_component_info *compptr,
    401                             JSAMPARRAY input_data, JSAMPARRAY output_data)
    402 {
    403  jsimd_h2v2_smooth_downsample_dspr2(input_data, output_data,
    404                                     compptr->v_samp_factor,
    405                                     cinfo->max_v_samp_factor,
    406                                     cinfo->smoothing_factor,
    407                                     compptr->width_in_blocks,
    408                                     cinfo->image_width);
    409 }
    410 
    411 GLOBAL(void)
    412 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
    413                      JSAMPARRAY input_data, JSAMPARRAY output_data)
    414 {
    415  jsimd_h2v1_downsample_dspr2(cinfo->image_width, cinfo->max_v_samp_factor,
    416                              compptr->v_samp_factor, compptr->width_in_blocks,
    417                              input_data, output_data);
    418 }
    419 
    420 GLOBAL(int)
    421 jsimd_can_h2v2_upsample(void)
    422 {
    423  init_simd();
    424 
    425  /* The code is optimised for these values only */
    426  if (BITS_IN_JSAMPLE != 8)
    427    return 0;
    428  if (sizeof(JDIMENSION) != 4)
    429    return 0;
    430 
    431  if (simd_support & JSIMD_DSPR2)
    432    return 1;
    433 
    434  return 0;
    435 }
    436 
    437 GLOBAL(int)
    438 jsimd_can_h2v1_upsample(void)
    439 {
    440  init_simd();
    441 
    442  /* The code is optimised for these values only */
    443  if (BITS_IN_JSAMPLE != 8)
    444    return 0;
    445  if (sizeof(JDIMENSION) != 4)
    446    return 0;
    447 
    448 #if defined(__MIPSEL__)
    449  if (simd_support & JSIMD_DSPR2)
    450    return 1;
    451 #endif
    452 
    453  return 0;
    454 }
    455 
    456 GLOBAL(int)
    457 jsimd_can_int_upsample(void)
    458 {
    459  init_simd();
    460 
    461  /* The code is optimised for these values only */
    462  if (BITS_IN_JSAMPLE != 8)
    463    return 0;
    464  if (sizeof(JDIMENSION) != 4)
    465    return 0;
    466 
    467  if (simd_support & JSIMD_DSPR2)
    468    return 1;
    469 
    470  return 0;
    471 }
    472 
    473 GLOBAL(void)
    474 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    475                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    476 {
    477  jsimd_h2v2_upsample_dspr2(cinfo->max_v_samp_factor, cinfo->output_width,
    478                            input_data, output_data_ptr);
    479 }
    480 
    481 GLOBAL(void)
    482 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    483                    JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    484 {
    485  jsimd_h2v1_upsample_dspr2(cinfo->max_v_samp_factor, cinfo->output_width,
    486                            input_data, output_data_ptr);
    487 }
    488 
    489 GLOBAL(void)
    490 jsimd_int_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    491                   JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    492 {
    493  my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
    494 
    495  jsimd_int_upsample_dspr2(upsample->h_expand[compptr->component_index],
    496                           upsample->v_expand[compptr->component_index],
    497                           input_data, output_data_ptr, cinfo->output_width,
    498                           cinfo->max_v_samp_factor);
    499 }
    500 
    501 GLOBAL(int)
    502 jsimd_can_h2v2_fancy_upsample(void)
    503 {
    504  init_simd();
    505 
    506  /* The code is optimised for these values only */
    507  if (BITS_IN_JSAMPLE != 8)
    508    return 0;
    509  if (sizeof(JDIMENSION) != 4)
    510    return 0;
    511 
    512 #if defined(__MIPSEL__)
    513  if (simd_support & JSIMD_DSPR2)
    514    return 1;
    515 #endif
    516 
    517  return 0;
    518 }
    519 
    520 GLOBAL(int)
    521 jsimd_can_h2v1_fancy_upsample(void)
    522 {
    523  init_simd();
    524 
    525  /* The code is optimised for these values only */
    526  if (BITS_IN_JSAMPLE != 8)
    527    return 0;
    528  if (sizeof(JDIMENSION) != 4)
    529    return 0;
    530 
    531 #if defined(__MIPSEL__)
    532  if (simd_support & JSIMD_DSPR2)
    533    return 1;
    534 #endif
    535 
    536  return 0;
    537 }
    538 
    539 GLOBAL(void)
    540 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    541                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    542 {
    543  jsimd_h2v2_fancy_upsample_dspr2(cinfo->max_v_samp_factor,
    544                                  compptr->downsampled_width, input_data,
    545                                  output_data_ptr);
    546 }
    547 
    548 GLOBAL(void)
    549 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    550                          JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
    551 {
    552  jsimd_h2v1_fancy_upsample_dspr2(cinfo->max_v_samp_factor,
    553                                  compptr->downsampled_width, input_data,
    554                                  output_data_ptr);
    555 }
    556 
    557 GLOBAL(int)
    558 jsimd_can_h2v2_merged_upsample(void)
    559 {
    560  init_simd();
    561 
    562  /* The code is optimised for these values only */
    563  if (BITS_IN_JSAMPLE != 8)
    564    return 0;
    565  if (sizeof(JDIMENSION) != 4)
    566    return 0;
    567 
    568  if (simd_support & JSIMD_DSPR2)
    569    return 1;
    570 
    571  return 0;
    572 }
    573 
    574 GLOBAL(int)
    575 jsimd_can_h2v1_merged_upsample(void)
    576 {
    577  init_simd();
    578 
    579  /* The code is optimised for these values only */
    580  if (BITS_IN_JSAMPLE != 8)
    581    return 0;
    582  if (sizeof(JDIMENSION) != 4)
    583    return 0;
    584 
    585  if (simd_support & JSIMD_DSPR2)
    586    return 1;
    587 
    588  return 0;
    589 }
    590 
    591 GLOBAL(void)
    592 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    593                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
    594 {
    595  void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, JSAMPLE *);
    596 
    597  switch (cinfo->out_color_space) {
    598  case JCS_EXT_RGB:
    599    dspr2fct = jsimd_h2v2_extrgb_merged_upsample_dspr2;
    600    break;
    601  case JCS_EXT_RGBX:
    602  case JCS_EXT_RGBA:
    603    dspr2fct = jsimd_h2v2_extrgbx_merged_upsample_dspr2;
    604    break;
    605  case JCS_EXT_BGR:
    606    dspr2fct = jsimd_h2v2_extbgr_merged_upsample_dspr2;
    607    break;
    608  case JCS_EXT_BGRX:
    609  case JCS_EXT_BGRA:
    610    dspr2fct = jsimd_h2v2_extbgrx_merged_upsample_dspr2;
    611    break;
    612  case JCS_EXT_XBGR:
    613  case JCS_EXT_ABGR:
    614    dspr2fct = jsimd_h2v2_extxbgr_merged_upsample_dspr2;
    615    break;
    616  case JCS_EXT_XRGB:
    617  case JCS_EXT_ARGB:
    618    dspr2fct = jsimd_h2v2_extxrgb_merged_upsample_dspr2;
    619    break;
    620  default:
    621    dspr2fct = jsimd_h2v2_extrgb_merged_upsample_dspr2;
    622    break;
    623  }
    624 
    625  dspr2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf,
    626           cinfo->sample_range_limit);
    627 }
    628 
    629 GLOBAL(void)
    630 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
    631                           JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
    632 {
    633  void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, JSAMPLE *);
    634 
    635  switch (cinfo->out_color_space) {
    636  case JCS_EXT_RGB:
    637    dspr2fct = jsimd_h2v1_extrgb_merged_upsample_dspr2;
    638    break;
    639  case JCS_EXT_RGBX:
    640  case JCS_EXT_RGBA:
    641    dspr2fct = jsimd_h2v1_extrgbx_merged_upsample_dspr2;
    642    break;
    643  case JCS_EXT_BGR:
    644    dspr2fct = jsimd_h2v1_extbgr_merged_upsample_dspr2;
    645    break;
    646  case JCS_EXT_BGRX:
    647  case JCS_EXT_BGRA:
    648    dspr2fct = jsimd_h2v1_extbgrx_merged_upsample_dspr2;
    649    break;
    650  case JCS_EXT_XBGR:
    651  case JCS_EXT_ABGR:
    652    dspr2fct = jsimd_h2v1_extxbgr_merged_upsample_dspr2;
    653    break;
    654  case JCS_EXT_XRGB:
    655  case JCS_EXT_ARGB:
    656    dspr2fct = jsimd_h2v1_extxrgb_merged_upsample_dspr2;
    657    break;
    658  default:
    659    dspr2fct = jsimd_h2v1_extrgb_merged_upsample_dspr2;
    660    break;
    661  }
    662 
    663  dspr2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf,
    664           cinfo->sample_range_limit);
    665 }
    666 
    667 GLOBAL(int)
    668 jsimd_can_convsamp(void)
    669 {
    670  init_simd();
    671 
    672  /* The code is optimised for these values only */
    673  if (DCTSIZE != 8)
    674    return 0;
    675  if (BITS_IN_JSAMPLE != 8)
    676    return 0;
    677  if (sizeof(JDIMENSION) != 4)
    678    return 0;
    679  if (sizeof(DCTELEM) != 2)
    680    return 0;
    681 
    682 #if defined(__MIPSEL__)
    683  if (simd_support & JSIMD_DSPR2)
    684    return 1;
    685 #endif
    686 
    687  return 0;
    688 }
    689 
    690 GLOBAL(int)
    691 jsimd_can_convsamp_float(void)
    692 {
    693  init_simd();
    694 
    695  /* The code is optimised for these values only */
    696  if (DCTSIZE != 8)
    697    return 0;
    698  if (sizeof(JCOEF) != 2)
    699    return 0;
    700  if (BITS_IN_JSAMPLE != 8)
    701    return 0;
    702  if (sizeof(JDIMENSION) != 4)
    703    return 0;
    704  if (sizeof(ISLOW_MULT_TYPE) != 2)
    705    return 0;
    706 
    707 #ifndef __mips_soft_float
    708  if (simd_support & JSIMD_DSPR2)
    709    return 1;
    710 #endif
    711 
    712  return 0;
    713 }
    714 
    715 GLOBAL(void)
    716 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
    717               DCTELEM *workspace)
    718 {
    719  jsimd_convsamp_dspr2(sample_data, start_col, workspace);
    720 }
    721 
    722 GLOBAL(void)
    723 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
    724                     FAST_FLOAT *workspace)
    725 {
    726 #ifndef __mips_soft_float
    727  jsimd_convsamp_float_dspr2(sample_data, start_col, workspace);
    728 #endif
    729 }
    730 
    731 GLOBAL(int)
    732 jsimd_can_fdct_islow(void)
    733 {
    734  init_simd();
    735 
    736  /* The code is optimised for these values only */
    737  if (DCTSIZE != 8)
    738    return 0;
    739  if (sizeof(DCTELEM) != 2)
    740    return 0;
    741 
    742 #if defined(__MIPSEL__)
    743  if (simd_support & JSIMD_DSPR2)
    744    return 1;
    745 #endif
    746 
    747  return 0;
    748 }
    749 
    750 GLOBAL(int)
    751 jsimd_can_fdct_ifast(void)
    752 {
    753  init_simd();
    754 
    755  /* The code is optimised for these values only */
    756  if (DCTSIZE != 8)
    757    return 0;
    758  if (sizeof(DCTELEM) != 2)
    759    return 0;
    760 
    761 #if defined(__MIPSEL__)
    762  if (simd_support & JSIMD_DSPR2)
    763    return 1;
    764 #endif
    765 
    766  return 0;
    767 }
    768 
    769 GLOBAL(int)
    770 jsimd_can_fdct_float(void)
    771 {
    772  return 0;
    773 }
    774 
    775 GLOBAL(void)
    776 jsimd_fdct_islow(DCTELEM *data)
    777 {
    778  jsimd_fdct_islow_dspr2(data);
    779 }
    780 
    781 GLOBAL(void)
    782 jsimd_fdct_ifast(DCTELEM *data)
    783 {
    784  jsimd_fdct_ifast_dspr2(data);
    785 }
    786 
    787 GLOBAL(void)
    788 jsimd_fdct_float(FAST_FLOAT *data)
    789 {
    790 }
    791 
    792 GLOBAL(int)
    793 jsimd_can_quantize(void)
    794 {
    795  init_simd();
    796 
    797  /* The code is optimised for these values only */
    798  if (DCTSIZE != 8)
    799    return 0;
    800  if (sizeof(JCOEF) != 2)
    801    return 0;
    802  if (sizeof(DCTELEM) != 2)
    803    return 0;
    804 
    805  if (simd_support & JSIMD_DSPR2)
    806    return 1;
    807 
    808  return 0;
    809 }
    810 
    811 GLOBAL(int)
    812 jsimd_can_quantize_float(void)
    813 {
    814  init_simd();
    815 
    816  /* The code is optimised for these values only */
    817  if (DCTSIZE != 8)
    818    return 0;
    819  if (sizeof(JCOEF) != 2)
    820    return 0;
    821  if (BITS_IN_JSAMPLE != 8)
    822    return 0;
    823  if (sizeof(JDIMENSION) != 4)
    824    return 0;
    825  if (sizeof(ISLOW_MULT_TYPE) != 2)
    826    return 0;
    827 
    828 #ifndef __mips_soft_float
    829  if (simd_support & JSIMD_DSPR2)
    830    return 1;
    831 #endif
    832 
    833  return 0;
    834 }
    835 
    836 GLOBAL(void)
    837 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
    838 {
    839  jsimd_quantize_dspr2(coef_block, divisors, workspace);
    840 }
    841 
    842 GLOBAL(void)
    843 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
    844                     FAST_FLOAT *workspace)
    845 {
    846 #ifndef __mips_soft_float
    847  jsimd_quantize_float_dspr2(coef_block, divisors, workspace);
    848 #endif
    849 }
    850 
    851 GLOBAL(int)
    852 jsimd_can_idct_2x2(void)
    853 {
    854  init_simd();
    855 
    856  /* The code is optimised for these values only */
    857  if (DCTSIZE != 8)
    858    return 0;
    859  if (sizeof(JCOEF) != 2)
    860    return 0;
    861  if (BITS_IN_JSAMPLE != 8)
    862    return 0;
    863  if (sizeof(JDIMENSION) != 4)
    864    return 0;
    865  if (sizeof(ISLOW_MULT_TYPE) != 2)
    866    return 0;
    867 
    868  if (simd_support & JSIMD_DSPR2)
    869    return 1;
    870 
    871  return 0;
    872 }
    873 
    874 GLOBAL(int)
    875 jsimd_can_idct_4x4(void)
    876 {
    877  init_simd();
    878 
    879  /* The code is optimised for these values only */
    880  if (DCTSIZE != 8)
    881    return 0;
    882  if (sizeof(JCOEF) != 2)
    883    return 0;
    884  if (BITS_IN_JSAMPLE != 8)
    885    return 0;
    886  if (sizeof(JDIMENSION) != 4)
    887    return 0;
    888  if (sizeof(ISLOW_MULT_TYPE) != 2)
    889    return 0;
    890 
    891 #if defined(__MIPSEL__)
    892  if (simd_support & JSIMD_DSPR2)
    893    return 1;
    894 #endif
    895 
    896  return 0;
    897 }
    898 
    899 GLOBAL(int)
    900 jsimd_can_idct_6x6(void)
    901 {
    902  init_simd();
    903 
    904  /* The code is optimised for these values only */
    905  if (DCTSIZE != 8)
    906    return 0;
    907  if (sizeof(JCOEF) != 2)
    908    return 0;
    909  if (BITS_IN_JSAMPLE != 8)
    910    return 0;
    911  if (sizeof(JDIMENSION) != 4)
    912    return 0;
    913  if (sizeof(ISLOW_MULT_TYPE) != 2)
    914    return 0;
    915 
    916  if (simd_support & JSIMD_DSPR2)
    917    return 1;
    918 
    919  return 0;
    920 }
    921 
    922 GLOBAL(int)
    923 jsimd_can_idct_12x12(void)
    924 {
    925  init_simd();
    926 
    927  if (BITS_IN_JSAMPLE != 8)
    928    return 0;
    929  if (DCTSIZE != 8)
    930    return 0;
    931  if (sizeof(JCOEF) != 2)
    932    return 0;
    933  if (sizeof(JDIMENSION) != 4)
    934    return 0;
    935  if (sizeof(ISLOW_MULT_TYPE) != 2)
    936    return 0;
    937 
    938  if (simd_support & JSIMD_DSPR2)
    939    return 1;
    940 
    941  return 0;
    942 }
    943 
    944 GLOBAL(void)
    945 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    946               JCOEFPTR coef_block, JSAMPARRAY output_buf,
    947               JDIMENSION output_col)
    948 {
    949  jsimd_idct_2x2_dspr2(compptr->dct_table, coef_block, output_buf, output_col);
    950 }
    951 
    952 GLOBAL(void)
    953 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    954               JCOEFPTR coef_block, JSAMPARRAY output_buf,
    955               JDIMENSION output_col)
    956 {
    957  int workspace[DCTSIZE * 4]; /* buffers data between passes */
    958 
    959  jsimd_idct_4x4_dspr2(compptr->dct_table, coef_block, output_buf, output_col,
    960                       workspace);
    961 }
    962 
    963 GLOBAL(void)
    964 jsimd_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    965               JCOEFPTR coef_block, JSAMPARRAY output_buf,
    966               JDIMENSION output_col)
    967 {
    968  jsimd_idct_6x6_dspr2(compptr->dct_table, coef_block, output_buf, output_col);
    969 }
    970 
    971 GLOBAL(void)
    972 jsimd_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
    973                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
    974                 JDIMENSION output_col)
    975 {
    976  int workspace[96];
    977  int output[12] = {
    978    (int)(output_buf[0] + output_col),
    979    (int)(output_buf[1] + output_col),
    980    (int)(output_buf[2] + output_col),
    981    (int)(output_buf[3] + output_col),
    982    (int)(output_buf[4] + output_col),
    983    (int)(output_buf[5] + output_col),
    984    (int)(output_buf[6] + output_col),
    985    (int)(output_buf[7] + output_col),
    986    (int)(output_buf[8] + output_col),
    987    (int)(output_buf[9] + output_col),
    988    (int)(output_buf[10] + output_col),
    989    (int)(output_buf[11] + output_col)
    990  };
    991 
    992  jsimd_idct_12x12_pass1_dspr2(coef_block, compptr->dct_table, workspace);
    993  jsimd_idct_12x12_pass2_dspr2(workspace, output);
    994 }
    995 
    996 GLOBAL(int)
    997 jsimd_can_idct_islow(void)
    998 {
    999  init_simd();
   1000 
   1001  /* The code is optimised for these values only */
   1002  if (DCTSIZE != 8)
   1003    return 0;
   1004  if (sizeof(JCOEF) != 2)
   1005    return 0;
   1006  if (BITS_IN_JSAMPLE != 8)
   1007    return 0;
   1008  if (sizeof(JDIMENSION) != 4)
   1009    return 0;
   1010  if (sizeof(ISLOW_MULT_TYPE) != 2)
   1011    return 0;
   1012 
   1013  if (simd_support & JSIMD_DSPR2)
   1014    return 1;
   1015 
   1016  return 0;
   1017 }
   1018 
   1019 GLOBAL(int)
   1020 jsimd_can_idct_ifast(void)
   1021 {
   1022  init_simd();
   1023 
   1024  /* The code is optimised for these values only */
   1025  if (DCTSIZE != 8)
   1026    return 0;
   1027  if (sizeof(JCOEF) != 2)
   1028    return 0;
   1029  if (BITS_IN_JSAMPLE != 8)
   1030    return 0;
   1031  if (sizeof(JDIMENSION) != 4)
   1032    return 0;
   1033  if (sizeof(IFAST_MULT_TYPE) != 2)
   1034    return 0;
   1035  if (IFAST_SCALE_BITS != 2)
   1036    return 0;
   1037 
   1038 #if defined(__MIPSEL__)
   1039  if (simd_support & JSIMD_DSPR2)
   1040    return 1;
   1041 #endif
   1042 
   1043  return 0;
   1044 }
   1045 
   1046 GLOBAL(int)
   1047 jsimd_can_idct_float(void)
   1048 {
   1049  return 0;
   1050 }
   1051 
   1052 GLOBAL(void)
   1053 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
   1054                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
   1055                 JDIMENSION output_col)
   1056 {
   1057  int output[8] = {
   1058    (int)(output_buf[0] + output_col),
   1059    (int)(output_buf[1] + output_col),
   1060    (int)(output_buf[2] + output_col),
   1061    (int)(output_buf[3] + output_col),
   1062    (int)(output_buf[4] + output_col),
   1063    (int)(output_buf[5] + output_col),
   1064    (int)(output_buf[6] + output_col),
   1065    (int)(output_buf[7] + output_col)
   1066  };
   1067 
   1068  jsimd_idct_islow_dspr2(coef_block, compptr->dct_table, output,
   1069                         IDCT_range_limit(cinfo));
   1070 }
   1071 
   1072 GLOBAL(void)
   1073 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
   1074                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
   1075                 JDIMENSION output_col)
   1076 {
   1077  JCOEFPTR inptr;
   1078  IFAST_MULT_TYPE *quantptr;
   1079  DCTELEM workspace[DCTSIZE2];  /* buffers data between passes */
   1080 
   1081  /* Pass 1: process columns from input, store into work array. */
   1082 
   1083  inptr = coef_block;
   1084  quantptr = (IFAST_MULT_TYPE *)compptr->dct_table;
   1085 
   1086  jsimd_idct_ifast_cols_dspr2(inptr, quantptr, workspace,
   1087                              mips_idct_ifast_coefs);
   1088 
   1089  /* Pass 2: process rows from work array, store into output array. */
   1090  /* Note that we must descale the results by a factor of 8 == 2**3, */
   1091  /* and also undo the PASS1_BITS scaling. */
   1092 
   1093  jsimd_idct_ifast_rows_dspr2(workspace, output_buf, output_col,
   1094                              mips_idct_ifast_coefs);
   1095 }
   1096 
   1097 GLOBAL(void)
   1098 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
   1099                 JCOEFPTR coef_block, JSAMPARRAY output_buf,
   1100                 JDIMENSION output_col)
   1101 {
   1102 }
   1103 
   1104 GLOBAL(int)
   1105 jsimd_can_huff_encode_one_block(void)
   1106 {
   1107  return 0;
   1108 }
   1109 
   1110 GLOBAL(JOCTET *)
   1111 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
   1112                            int last_dc_val, c_derived_tbl *dctbl,
   1113                            c_derived_tbl *actbl)
   1114 {
   1115  return NULL;
   1116 }
   1117 
   1118 GLOBAL(int)
   1119 jsimd_can_encode_mcu_AC_first_prepare(void)
   1120 {
   1121  return 0;
   1122 }
   1123 
   1124 GLOBAL(void)
   1125 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
   1126                                  const int *jpeg_natural_order_start, int Sl,
   1127                                  int Al, UJCOEF *values, size_t *zerobits)
   1128 {
   1129 }
   1130 
   1131 GLOBAL(int)
   1132 jsimd_can_encode_mcu_AC_refine_prepare(void)
   1133 {
   1134  return 0;
   1135 }
   1136 
   1137 GLOBAL(int)
   1138 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
   1139                                   const int *jpeg_natural_order_start, int Sl,
   1140                                   int Al, UJCOEF *absvalues, size_t *bits)
   1141 {
   1142  return 0;
   1143 }