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