1 /*
2  * jsimd_mips.c
3  *
4  * Copyright 2009 Pierre Ossman <ossman@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)
parse_proc_cpuinfo(const char * search_string)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)
init_simd(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)
jsimd_can_rgb_ycc(void)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)
jsimd_can_rgb_gray(void)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)
jsimd_can_ycc_rgb(void)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)
jsimd_can_ycc_rgb565(void)165 jsimd_can_ycc_rgb565 (void)
166 {
167   return 0;
168 }
169 
170 GLOBAL(int)
jsimd_c_can_null_convert(void)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)
jsimd_rgb_ycc_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)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)
jsimd_rgb_gray_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)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)
jsimd_ycc_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)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)
jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)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)
jsimd_c_null_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)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)
jsimd_can_h2v2_downsample(void)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)
jsimd_can_h2v2_smooth_downsample(void)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)
jsimd_can_h2v1_downsample(void)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)
jsimd_h2v2_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)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)
jsimd_h2v2_smooth_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)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)
jsimd_h2v1_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)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)
jsimd_can_h2v2_upsample(void)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)
jsimd_can_h2v1_upsample(void)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)
jsimd_can_int_upsample(void)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)
jsimd_h2v2_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)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)
jsimd_h2v1_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)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)
jsimd_int_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)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)
jsimd_can_h2v2_fancy_upsample(void)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)
jsimd_can_h2v1_fancy_upsample(void)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)
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)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)
jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)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)
jsimd_can_h2v2_merged_upsample(void)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)
jsimd_can_h2v1_merged_upsample(void)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)
jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)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)
jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)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)
jsimd_can_convsamp(void)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)
jsimd_can_convsamp_float(void)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)
jsimd_convsamp(JSAMPARRAY sample_data,JDIMENSION start_col,DCTELEM * workspace)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)
jsimd_convsamp_float(JSAMPARRAY sample_data,JDIMENSION start_col,FAST_FLOAT * workspace)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)
jsimd_can_fdct_islow(void)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)
jsimd_can_fdct_ifast(void)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)
jsimd_can_fdct_float(void)771 jsimd_can_fdct_float (void)
772 {
773   init_simd();
774 
775   return 0;
776 }
777 
778 GLOBAL(void)
jsimd_fdct_islow(DCTELEM * data)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)
jsimd_fdct_ifast(DCTELEM * data)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)
jsimd_fdct_float(FAST_FLOAT * data)793 jsimd_fdct_float (FAST_FLOAT * data)
794 {
795 }
796 
797 GLOBAL(int)
jsimd_can_quantize(void)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)
jsimd_can_quantize_float(void)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)
jsimd_quantize(JCOEFPTR coef_block,DCTELEM * divisors,DCTELEM * workspace)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)
jsimd_quantize_float(JCOEFPTR coef_block,FAST_FLOAT * divisors,FAST_FLOAT * workspace)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)
jsimd_can_idct_2x2(void)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)
jsimd_can_idct_4x4(void)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)
jsimd_can_idct_6x6(void)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)
jsimd_can_idct_12x12(void)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)
jsimd_idct_2x2(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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)
jsimd_idct_4x4(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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)
jsimd_idct_6x6(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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)
jsimd_idct_12x12(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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)
jsimd_can_idct_islow(void)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)
jsimd_can_idct_ifast(void)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)
jsimd_can_idct_float(void)1054 jsimd_can_idct_float (void)
1055 {
1056   init_simd();
1057 
1058   return 0;
1059 }
1060 
1061 GLOBAL(void)
jsimd_idct_islow(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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)
jsimd_idct_ifast(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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)
jsimd_idct_float(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)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