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