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