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