• 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, 2018, 2020, D. R. Commander.
6  * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
7  * Copyright (C) 2015-2016, 2018, 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 <ctype.h>
27 
28 static unsigned int simd_support = ~0;
29 
30 #if !(defined(__mips_dsp) && (__mips_dsp_rev >= 2)) && defined(__linux__)
31 
32 LOCAL(void)
parse_proc_cpuinfo(const char * search_string)33 parse_proc_cpuinfo(const char *search_string)
34 {
35   const char *file_name = "/proc/cpuinfo";
36   char cpuinfo_line[256];
37   FILE *f = NULL;
38 
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_DSPR2;
46         return;
47       }
48     }
49     fclose(f);
50   }
51   /* Did not find string in the proc file, or not Linux ELF. */
52 }
53 
54 #endif
55 
56 /*
57  * Check what SIMD accelerations are supported.
58  *
59  * FIXME: This code is racy under a multi-threaded environment.
60  */
61 LOCAL(void)
init_simd(void)62 init_simd(void)
63 {
64 #ifndef NO_GETENV
65   char *env = NULL;
66 #endif
67 
68   if (simd_support != ~0U)
69     return;
70 
71   simd_support = 0;
72 
73 #if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
74   simd_support |= JSIMD_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   parse_proc_cpuinfo("MIPS 74K");
80 #endif
81 
82 #ifndef NO_GETENV
83   /* Force different settings through environment variables */
84   env = getenv("JSIMD_FORCEDSPR2");
85   if ((env != NULL) && (strcmp(env, "1") == 0))
86     simd_support = JSIMD_DSPR2;
87   env = getenv("JSIMD_FORCENONE");
88   if ((env != NULL) && (strcmp(env, "1") == 0))
89     simd_support = 0;
90 #endif
91 }
92 
93 static const int mips_idct_ifast_coefs[4] = {
94   0x45404540,           /* FIX( 1.082392200 / 2) =  17734 = 0x4546 */
95   0x5A805A80,           /* FIX( 1.414213562 / 2) =  23170 = 0x5A82 */
96   0x76407640,           /* FIX( 1.847759065 / 2) =  30274 = 0x7642 */
97   0xAC60AC60            /* FIX(-2.613125930 / 4) = -21407 = 0xAC61 */
98 };
99 
100 /* The following struct is borrowed from jdsample.c */
101 typedef void (*upsample1_ptr) (j_decompress_ptr cinfo,
102                                jpeg_component_info *compptr,
103                                JSAMPARRAY input_data,
104                                JSAMPARRAY *output_data_ptr);
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_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_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_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_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, JSAMPARRAY input_buf,
200                       JSAMPIMAGE output_buf, JDIMENSION output_row,
201                       int num_rows)
202 {
203   void (*dspr2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
204 
205   switch (cinfo->in_color_space) {
206   case JCS_EXT_RGB:
207     dspr2fct = jsimd_extrgb_ycc_convert_dspr2;
208     break;
209   case JCS_EXT_RGBX:
210   case JCS_EXT_RGBA:
211     dspr2fct = jsimd_extrgbx_ycc_convert_dspr2;
212     break;
213   case JCS_EXT_BGR:
214     dspr2fct = jsimd_extbgr_ycc_convert_dspr2;
215     break;
216   case JCS_EXT_BGRX:
217   case JCS_EXT_BGRA:
218     dspr2fct = jsimd_extbgrx_ycc_convert_dspr2;
219     break;
220   case JCS_EXT_XBGR:
221   case JCS_EXT_ABGR:
222     dspr2fct = jsimd_extxbgr_ycc_convert_dspr2;
223     break;
224   case JCS_EXT_XRGB:
225   case JCS_EXT_ARGB:
226     dspr2fct = jsimd_extxrgb_ycc_convert_dspr2;
227     break;
228   default:
229     dspr2fct = jsimd_extrgb_ycc_convert_dspr2;
230     break;
231   }
232 
233   dspr2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
234 }
235 
236 GLOBAL(void)
jsimd_rgb_gray_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)237 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
238                        JSAMPIMAGE output_buf, JDIMENSION output_row,
239                        int num_rows)
240 {
241   void (*dspr2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
242 
243   switch (cinfo->in_color_space) {
244   case JCS_EXT_RGB:
245     dspr2fct = jsimd_extrgb_gray_convert_dspr2;
246     break;
247   case JCS_EXT_RGBX:
248   case JCS_EXT_RGBA:
249     dspr2fct = jsimd_extrgbx_gray_convert_dspr2;
250     break;
251   case JCS_EXT_BGR:
252     dspr2fct = jsimd_extbgr_gray_convert_dspr2;
253     break;
254   case JCS_EXT_BGRX:
255   case JCS_EXT_BGRA:
256     dspr2fct = jsimd_extbgrx_gray_convert_dspr2;
257     break;
258   case JCS_EXT_XBGR:
259   case JCS_EXT_ABGR:
260     dspr2fct = jsimd_extxbgr_gray_convert_dspr2;
261     break;
262   case JCS_EXT_XRGB:
263   case JCS_EXT_ARGB:
264     dspr2fct = jsimd_extxrgb_gray_convert_dspr2;
265     break;
266   default:
267     dspr2fct = jsimd_extrgb_gray_convert_dspr2;
268     break;
269   }
270 
271   dspr2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
272 }
273 
274 GLOBAL(void)
jsimd_ycc_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)275 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
276                       JDIMENSION input_row, JSAMPARRAY output_buf,
277                       int num_rows)
278 {
279   void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
280 
281   switch (cinfo->out_color_space) {
282   case JCS_EXT_RGB:
283     dspr2fct = jsimd_ycc_extrgb_convert_dspr2;
284     break;
285   case JCS_EXT_RGBX:
286   case JCS_EXT_RGBA:
287     dspr2fct = jsimd_ycc_extrgbx_convert_dspr2;
288     break;
289   case JCS_EXT_BGR:
290     dspr2fct = jsimd_ycc_extbgr_convert_dspr2;
291     break;
292   case JCS_EXT_BGRX:
293   case JCS_EXT_BGRA:
294     dspr2fct = jsimd_ycc_extbgrx_convert_dspr2;
295     break;
296   case JCS_EXT_XBGR:
297   case JCS_EXT_ABGR:
298     dspr2fct = jsimd_ycc_extxbgr_convert_dspr2;
299     break;
300   case JCS_EXT_XRGB:
301   case JCS_EXT_ARGB:
302     dspr2fct = jsimd_ycc_extxrgb_convert_dspr2;
303     break;
304   default:
305     dspr2fct = jsimd_ycc_extrgb_convert_dspr2;
306     break;
307   }
308 
309   dspr2fct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
310 }
311 
312 GLOBAL(void)
jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)313 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
314                          JDIMENSION input_row, JSAMPARRAY output_buf,
315                          int num_rows)
316 {
317 }
318 
319 GLOBAL(void)
jsimd_c_null_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)320 jsimd_c_null_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
321                      JSAMPIMAGE output_buf, JDIMENSION output_row,
322                      int num_rows)
323 {
324   jsimd_c_null_convert_dspr2(cinfo->image_width, input_buf, output_buf,
325                              output_row, num_rows, cinfo->num_components);
326 }
327 
328 GLOBAL(int)
jsimd_can_h2v2_downsample(void)329 jsimd_can_h2v2_downsample(void)
330 {
331   init_simd();
332 
333   /* The code is optimised for these values only */
334   if (BITS_IN_JSAMPLE != 8)
335     return 0;
336   if (sizeof(JDIMENSION) != 4)
337     return 0;
338 
339   /* FIXME: jsimd_h2v2_downsample_dspr2() fails some of the TJBench tiling
340    * regression tests, probably because the DSPr2 SIMD implementation predates
341    * those tests. */
342 #if 0
343   if (simd_support & JSIMD_DSPR2)
344     return 1;
345 #endif
346 
347   return 0;
348 }
349 
350 GLOBAL(int)
jsimd_can_h2v2_smooth_downsample(void)351 jsimd_can_h2v2_smooth_downsample(void)
352 {
353   init_simd();
354 
355   /* The code is optimised for these values only */
356   if (BITS_IN_JSAMPLE != 8)
357     return 0;
358   if (sizeof(JDIMENSION) != 4)
359     return 0;
360   if (DCTSIZE != 8)
361     return 0;
362 
363   if (simd_support & JSIMD_DSPR2)
364     return 1;
365 
366   return 0;
367 }
368 
369 GLOBAL(int)
jsimd_can_h2v1_downsample(void)370 jsimd_can_h2v1_downsample(void)
371 {
372   init_simd();
373 
374   /* The code is optimised for these values only */
375   if (BITS_IN_JSAMPLE != 8)
376     return 0;
377   if (sizeof(JDIMENSION) != 4)
378     return 0;
379 
380   /* FIXME: jsimd_h2v1_downsample_dspr2() fails some of the TJBench tiling
381    * regression tests, probably because the DSPr2 SIMD implementation predates
382    * those tests. */
383 #if 0
384   if (simd_support & JSIMD_DSPR2)
385     return 1;
386 #endif
387 
388   return 0;
389 }
390 
391 GLOBAL(void)
jsimd_h2v2_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)392 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
393                       JSAMPARRAY input_data, JSAMPARRAY output_data)
394 {
395   jsimd_h2v2_downsample_dspr2(cinfo->image_width, cinfo->max_v_samp_factor,
396                               compptr->v_samp_factor, compptr->width_in_blocks,
397                               input_data, 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_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   jsimd_h2v1_downsample_dspr2(cinfo->image_width, cinfo->max_v_samp_factor,
418                               compptr->v_samp_factor, compptr->width_in_blocks,
419                               input_data, output_data);
420 }
421 
422 GLOBAL(int)
jsimd_can_h2v2_upsample(void)423 jsimd_can_h2v2_upsample(void)
424 {
425   init_simd();
426 
427   /* The code is optimised for these values only */
428   if (BITS_IN_JSAMPLE != 8)
429     return 0;
430   if (sizeof(JDIMENSION) != 4)
431     return 0;
432 
433   if (simd_support & JSIMD_DSPR2)
434     return 1;
435 
436   return 0;
437 }
438 
439 GLOBAL(int)
jsimd_can_h2v1_upsample(void)440 jsimd_can_h2v1_upsample(void)
441 {
442   init_simd();
443 
444   /* The code is optimised for these values only */
445   if (BITS_IN_JSAMPLE != 8)
446     return 0;
447   if (sizeof(JDIMENSION) != 4)
448     return 0;
449 
450 #if defined(__MIPSEL__)
451   if (simd_support & JSIMD_DSPR2)
452     return 1;
453 #endif
454 
455   return 0;
456 }
457 
458 GLOBAL(int)
jsimd_can_int_upsample(void)459 jsimd_can_int_upsample(void)
460 {
461   init_simd();
462 
463   /* The code is optimised for these values only */
464   if (BITS_IN_JSAMPLE != 8)
465     return 0;
466   if (sizeof(JDIMENSION) != 4)
467     return 0;
468 
469   if (simd_support & JSIMD_DSPR2)
470     return 1;
471 
472   return 0;
473 }
474 
475 GLOBAL(void)
jsimd_h2v2_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)476 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
477                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
478 {
479   jsimd_h2v2_upsample_dspr2(cinfo->max_v_samp_factor, cinfo->output_width,
480                             input_data, output_data_ptr);
481 }
482 
483 GLOBAL(void)
jsimd_h2v1_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)484 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
485                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
486 {
487   jsimd_h2v1_upsample_dspr2(cinfo->max_v_samp_factor, cinfo->output_width,
488                             input_data, 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_dspr2(upsample->h_expand[compptr->component_index],
498                            upsample->v_expand[compptr->component_index],
499                            input_data, output_data_ptr, cinfo->output_width,
500                            cinfo->max_v_samp_factor);
501 }
502 
503 GLOBAL(int)
jsimd_can_h2v2_fancy_upsample(void)504 jsimd_can_h2v2_fancy_upsample(void)
505 {
506   init_simd();
507 
508   /* The code is optimised for these values only */
509   if (BITS_IN_JSAMPLE != 8)
510     return 0;
511   if (sizeof(JDIMENSION) != 4)
512     return 0;
513 
514 #if defined(__MIPSEL__)
515   if (simd_support & JSIMD_DSPR2)
516     return 1;
517 #endif
518 
519   return 0;
520 }
521 
522 GLOBAL(int)
jsimd_can_h2v1_fancy_upsample(void)523 jsimd_can_h2v1_fancy_upsample(void)
524 {
525   init_simd();
526 
527   /* The code is optimised for these values only */
528   if (BITS_IN_JSAMPLE != 8)
529     return 0;
530   if (sizeof(JDIMENSION) != 4)
531     return 0;
532 
533 #if defined(__MIPSEL__)
534   if (simd_support & JSIMD_DSPR2)
535     return 1;
536 #endif
537 
538   return 0;
539 }
540 
541 GLOBAL(void)
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)542 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
543                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
544 {
545   jsimd_h2v2_fancy_upsample_dspr2(cinfo->max_v_samp_factor,
546                                   compptr->downsampled_width, input_data,
547                                   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, jpeg_component_info *compptr,
552                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
553 {
554   jsimd_h2v1_fancy_upsample_dspr2(cinfo->max_v_samp_factor,
555                                   compptr->downsampled_width, input_data,
556                                   output_data_ptr);
557 }
558 
559 GLOBAL(int)
jsimd_can_h2v2_merged_upsample(void)560 jsimd_can_h2v2_merged_upsample(void)
561 {
562   init_simd();
563 
564   /* The code is optimised for these values only */
565   if (BITS_IN_JSAMPLE != 8)
566     return 0;
567   if (sizeof(JDIMENSION) != 4)
568     return 0;
569 
570   if (simd_support & JSIMD_DSPR2)
571     return 1;
572 
573   return 0;
574 }
575 
576 GLOBAL(int)
jsimd_can_h2v1_merged_upsample(void)577 jsimd_can_h2v1_merged_upsample(void)
578 {
579   init_simd();
580 
581   /* The code is optimised for these values only */
582   if (BITS_IN_JSAMPLE != 8)
583     return 0;
584   if (sizeof(JDIMENSION) != 4)
585     return 0;
586 
587   if (simd_support & JSIMD_DSPR2)
588     return 1;
589 
590   return 0;
591 }
592 
593 GLOBAL(void)
jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)594 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
595                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
596 {
597   void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, JSAMPLE *);
598 
599   switch (cinfo->out_color_space) {
600   case JCS_EXT_RGB:
601     dspr2fct = jsimd_h2v2_extrgb_merged_upsample_dspr2;
602     break;
603   case JCS_EXT_RGBX:
604   case JCS_EXT_RGBA:
605     dspr2fct = jsimd_h2v2_extrgbx_merged_upsample_dspr2;
606     break;
607   case JCS_EXT_BGR:
608     dspr2fct = jsimd_h2v2_extbgr_merged_upsample_dspr2;
609     break;
610   case JCS_EXT_BGRX:
611   case JCS_EXT_BGRA:
612     dspr2fct = jsimd_h2v2_extbgrx_merged_upsample_dspr2;
613     break;
614   case JCS_EXT_XBGR:
615   case JCS_EXT_ABGR:
616     dspr2fct = jsimd_h2v2_extxbgr_merged_upsample_dspr2;
617     break;
618   case JCS_EXT_XRGB:
619   case JCS_EXT_ARGB:
620     dspr2fct = jsimd_h2v2_extxrgb_merged_upsample_dspr2;
621     break;
622   default:
623     dspr2fct = jsimd_h2v2_extrgb_merged_upsample_dspr2;
624     break;
625   }
626 
627   dspr2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf,
628            cinfo->sample_range_limit);
629 }
630 
631 GLOBAL(void)
jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)632 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
633                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
634 {
635   void (*dspr2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, JSAMPLE *);
636 
637   switch (cinfo->out_color_space) {
638   case JCS_EXT_RGB:
639     dspr2fct = jsimd_h2v1_extrgb_merged_upsample_dspr2;
640     break;
641   case JCS_EXT_RGBX:
642   case JCS_EXT_RGBA:
643     dspr2fct = jsimd_h2v1_extrgbx_merged_upsample_dspr2;
644     break;
645   case JCS_EXT_BGR:
646     dspr2fct = jsimd_h2v1_extbgr_merged_upsample_dspr2;
647     break;
648   case JCS_EXT_BGRX:
649   case JCS_EXT_BGRA:
650     dspr2fct = jsimd_h2v1_extbgrx_merged_upsample_dspr2;
651     break;
652   case JCS_EXT_XBGR:
653   case JCS_EXT_ABGR:
654     dspr2fct = jsimd_h2v1_extxbgr_merged_upsample_dspr2;
655     break;
656   case JCS_EXT_XRGB:
657   case JCS_EXT_ARGB:
658     dspr2fct = jsimd_h2v1_extxrgb_merged_upsample_dspr2;
659     break;
660   default:
661     dspr2fct = jsimd_h2v1_extrgb_merged_upsample_dspr2;
662     break;
663   }
664 
665   dspr2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf,
666            cinfo->sample_range_limit);
667 }
668 
669 GLOBAL(int)
jsimd_can_convsamp(void)670 jsimd_can_convsamp(void)
671 {
672   init_simd();
673 
674   /* The code is optimised for these values only */
675   if (DCTSIZE != 8)
676     return 0;
677   if (BITS_IN_JSAMPLE != 8)
678     return 0;
679   if (sizeof(JDIMENSION) != 4)
680     return 0;
681   if (sizeof(DCTELEM) != 2)
682     return 0;
683 
684 #if defined(__MIPSEL__)
685   if (simd_support & JSIMD_DSPR2)
686     return 1;
687 #endif
688 
689   return 0;
690 }
691 
692 GLOBAL(int)
jsimd_can_convsamp_float(void)693 jsimd_can_convsamp_float(void)
694 {
695   init_simd();
696 
697   /* The code is optimised for these values only */
698   if (DCTSIZE != 8)
699     return 0;
700   if (sizeof(JCOEF) != 2)
701     return 0;
702   if (BITS_IN_JSAMPLE != 8)
703     return 0;
704   if (sizeof(JDIMENSION) != 4)
705     return 0;
706   if (sizeof(ISLOW_MULT_TYPE) != 2)
707     return 0;
708 
709 #ifndef __mips_soft_float
710   if (simd_support & JSIMD_DSPR2)
711     return 1;
712 #endif
713 
714   return 0;
715 }
716 
717 GLOBAL(void)
jsimd_convsamp(JSAMPARRAY sample_data,JDIMENSION start_col,DCTELEM * workspace)718 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
719                DCTELEM *workspace)
720 {
721   jsimd_convsamp_dspr2(sample_data, start_col, workspace);
722 }
723 
724 GLOBAL(void)
jsimd_convsamp_float(JSAMPARRAY sample_data,JDIMENSION start_col,FAST_FLOAT * workspace)725 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
726                      FAST_FLOAT *workspace)
727 {
728 #ifndef __mips_soft_float
729   jsimd_convsamp_float_dspr2(sample_data, start_col, workspace);
730 #endif
731 }
732 
733 GLOBAL(int)
jsimd_can_fdct_islow(void)734 jsimd_can_fdct_islow(void)
735 {
736   init_simd();
737 
738   /* The code is optimised for these values only */
739   if (DCTSIZE != 8)
740     return 0;
741   if (sizeof(DCTELEM) != 2)
742     return 0;
743 
744 #if defined(__MIPSEL__)
745   if (simd_support & JSIMD_DSPR2)
746     return 1;
747 #endif
748 
749   return 0;
750 }
751 
752 GLOBAL(int)
jsimd_can_fdct_ifast(void)753 jsimd_can_fdct_ifast(void)
754 {
755   init_simd();
756 
757   /* The code is optimised for these values only */
758   if (DCTSIZE != 8)
759     return 0;
760   if (sizeof(DCTELEM) != 2)
761     return 0;
762 
763 #if defined(__MIPSEL__)
764   if (simd_support & JSIMD_DSPR2)
765     return 1;
766 #endif
767 
768   return 0;
769 }
770 
771 GLOBAL(int)
jsimd_can_fdct_float(void)772 jsimd_can_fdct_float(void)
773 {
774   return 0;
775 }
776 
777 GLOBAL(void)
jsimd_fdct_islow(DCTELEM * data)778 jsimd_fdct_islow(DCTELEM *data)
779 {
780   jsimd_fdct_islow_dspr2(data);
781 }
782 
783 GLOBAL(void)
jsimd_fdct_ifast(DCTELEM * data)784 jsimd_fdct_ifast(DCTELEM *data)
785 {
786   jsimd_fdct_ifast_dspr2(data);
787 }
788 
789 GLOBAL(void)
jsimd_fdct_float(FAST_FLOAT * data)790 jsimd_fdct_float(FAST_FLOAT *data)
791 {
792 }
793 
794 GLOBAL(int)
jsimd_can_quantize(void)795 jsimd_can_quantize(void)
796 {
797   init_simd();
798 
799   /* The code is optimised for these values only */
800   if (DCTSIZE != 8)
801     return 0;
802   if (sizeof(JCOEF) != 2)
803     return 0;
804   if (sizeof(DCTELEM) != 2)
805     return 0;
806 
807   if (simd_support & JSIMD_DSPR2)
808     return 1;
809 
810   return 0;
811 }
812 
813 GLOBAL(int)
jsimd_can_quantize_float(void)814 jsimd_can_quantize_float(void)
815 {
816   init_simd();
817 
818   /* The code is optimised for these values only */
819   if (DCTSIZE != 8)
820     return 0;
821   if (sizeof(JCOEF) != 2)
822     return 0;
823   if (BITS_IN_JSAMPLE != 8)
824     return 0;
825   if (sizeof(JDIMENSION) != 4)
826     return 0;
827   if (sizeof(ISLOW_MULT_TYPE) != 2)
828     return 0;
829 
830 #ifndef __mips_soft_float
831   if (simd_support & JSIMD_DSPR2)
832     return 1;
833 #endif
834 
835   return 0;
836 }
837 
838 GLOBAL(void)
jsimd_quantize(JCOEFPTR coef_block,DCTELEM * divisors,DCTELEM * workspace)839 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
840 {
841   jsimd_quantize_dspr2(coef_block, divisors, workspace);
842 }
843 
844 GLOBAL(void)
jsimd_quantize_float(JCOEFPTR coef_block,FAST_FLOAT * divisors,FAST_FLOAT * workspace)845 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
846                      FAST_FLOAT *workspace)
847 {
848 #ifndef __mips_soft_float
849   jsimd_quantize_float_dspr2(coef_block, divisors, workspace);
850 #endif
851 }
852 
853 GLOBAL(int)
jsimd_can_idct_2x2(void)854 jsimd_can_idct_2x2(void)
855 {
856   init_simd();
857 
858   /* The code is optimised for these values only */
859   if (DCTSIZE != 8)
860     return 0;
861   if (sizeof(JCOEF) != 2)
862     return 0;
863   if (BITS_IN_JSAMPLE != 8)
864     return 0;
865   if (sizeof(JDIMENSION) != 4)
866     return 0;
867   if (sizeof(ISLOW_MULT_TYPE) != 2)
868     return 0;
869 
870   if (simd_support & JSIMD_DSPR2)
871     return 1;
872 
873   return 0;
874 }
875 
876 GLOBAL(int)
jsimd_can_idct_4x4(void)877 jsimd_can_idct_4x4(void)
878 {
879   init_simd();
880 
881   /* The code is optimised for these values only */
882   if (DCTSIZE != 8)
883     return 0;
884   if (sizeof(JCOEF) != 2)
885     return 0;
886   if (BITS_IN_JSAMPLE != 8)
887     return 0;
888   if (sizeof(JDIMENSION) != 4)
889     return 0;
890   if (sizeof(ISLOW_MULT_TYPE) != 2)
891     return 0;
892 
893 #if defined(__MIPSEL__)
894   if (simd_support & JSIMD_DSPR2)
895     return 1;
896 #endif
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_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_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   jsimd_idct_2x2_dspr2(compptr->dct_table, coef_block, output_buf, output_col);
952 }
953 
954 GLOBAL(void)
jsimd_idct_4x4(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)955 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
956                JCOEFPTR coef_block, JSAMPARRAY output_buf,
957                JDIMENSION output_col)
958 {
959   int workspace[DCTSIZE * 4]; /* buffers data between passes */
960 
961   jsimd_idct_4x4_dspr2(compptr->dct_table, coef_block, output_buf, output_col,
962                        workspace);
963 }
964 
965 GLOBAL(void)
jsimd_idct_6x6(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)966 jsimd_idct_6x6(j_decompress_ptr cinfo, jpeg_component_info *compptr,
967                JCOEFPTR coef_block, JSAMPARRAY output_buf,
968                JDIMENSION output_col)
969 {
970   jsimd_idct_6x6_dspr2(compptr->dct_table, coef_block, output_buf, output_col);
971 }
972 
973 GLOBAL(void)
jsimd_idct_12x12(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)974 jsimd_idct_12x12(j_decompress_ptr cinfo, jpeg_component_info *compptr,
975                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
976                  JDIMENSION output_col)
977 {
978   int workspace[96];
979   int output[12] = {
980     (int)(output_buf[0] + output_col),
981     (int)(output_buf[1] + output_col),
982     (int)(output_buf[2] + output_col),
983     (int)(output_buf[3] + output_col),
984     (int)(output_buf[4] + output_col),
985     (int)(output_buf[5] + output_col),
986     (int)(output_buf[6] + output_col),
987     (int)(output_buf[7] + output_col),
988     (int)(output_buf[8] + output_col),
989     (int)(output_buf[9] + output_col),
990     (int)(output_buf[10] + output_col),
991     (int)(output_buf[11] + output_col)
992   };
993 
994   jsimd_idct_12x12_pass1_dspr2(coef_block, compptr->dct_table, workspace);
995   jsimd_idct_12x12_pass2_dspr2(workspace, output);
996 }
997 
998 GLOBAL(int)
jsimd_can_idct_islow(void)999 jsimd_can_idct_islow(void)
1000 {
1001   init_simd();
1002 
1003   /* The code is optimised for these values only */
1004   if (DCTSIZE != 8)
1005     return 0;
1006   if (sizeof(JCOEF) != 2)
1007     return 0;
1008   if (BITS_IN_JSAMPLE != 8)
1009     return 0;
1010   if (sizeof(JDIMENSION) != 4)
1011     return 0;
1012   if (sizeof(ISLOW_MULT_TYPE) != 2)
1013     return 0;
1014 
1015   if (simd_support & JSIMD_DSPR2)
1016     return 1;
1017 
1018   return 0;
1019 }
1020 
1021 GLOBAL(int)
jsimd_can_idct_ifast(void)1022 jsimd_can_idct_ifast(void)
1023 {
1024   init_simd();
1025 
1026   /* The code is optimised for these values only */
1027   if (DCTSIZE != 8)
1028     return 0;
1029   if (sizeof(JCOEF) != 2)
1030     return 0;
1031   if (BITS_IN_JSAMPLE != 8)
1032     return 0;
1033   if (sizeof(JDIMENSION) != 4)
1034     return 0;
1035   if (sizeof(IFAST_MULT_TYPE) != 2)
1036     return 0;
1037   if (IFAST_SCALE_BITS != 2)
1038     return 0;
1039 
1040 #if defined(__MIPSEL__)
1041   if (simd_support & JSIMD_DSPR2)
1042     return 1;
1043 #endif
1044 
1045   return 0;
1046 }
1047 
1048 GLOBAL(int)
jsimd_can_idct_float(void)1049 jsimd_can_idct_float(void)
1050 {
1051   return 0;
1052 }
1053 
1054 GLOBAL(void)
jsimd_idct_islow(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)1055 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1056                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1057                  JDIMENSION output_col)
1058 {
1059   int output[8] = {
1060     (int)(output_buf[0] + output_col),
1061     (int)(output_buf[1] + output_col),
1062     (int)(output_buf[2] + output_col),
1063     (int)(output_buf[3] + output_col),
1064     (int)(output_buf[4] + output_col),
1065     (int)(output_buf[5] + output_col),
1066     (int)(output_buf[6] + output_col),
1067     (int)(output_buf[7] + output_col)
1068   };
1069 
1070   jsimd_idct_islow_dspr2(coef_block, compptr->dct_table, output,
1071                          IDCT_range_limit(cinfo));
1072 }
1073 
1074 GLOBAL(void)
jsimd_idct_ifast(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)1075 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1076                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1077                  JDIMENSION output_col)
1078 {
1079   JCOEFPTR inptr;
1080   IFAST_MULT_TYPE *quantptr;
1081   DCTELEM workspace[DCTSIZE2];  /* buffers data between passes */
1082 
1083   /* Pass 1: process columns from input, store into work array. */
1084 
1085   inptr = coef_block;
1086   quantptr = (IFAST_MULT_TYPE *)compptr->dct_table;
1087 
1088   jsimd_idct_ifast_cols_dspr2(inptr, quantptr, workspace,
1089                               mips_idct_ifast_coefs);
1090 
1091   /* Pass 2: process rows from work array, store into output array. */
1092   /* Note that we must descale the results by a factor of 8 == 2**3, */
1093   /* and also undo the PASS1_BITS scaling. */
1094 
1095   jsimd_idct_ifast_rows_dspr2(workspace, output_buf, output_col,
1096                               mips_idct_ifast_coefs);
1097 }
1098 
1099 GLOBAL(void)
jsimd_idct_float(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)1100 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1101                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1102                  JDIMENSION output_col)
1103 {
1104 }
1105 
1106 GLOBAL(int)
jsimd_can_huff_encode_one_block(void)1107 jsimd_can_huff_encode_one_block(void)
1108 {
1109   return 0;
1110 }
1111 
1112 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)1113 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
1114                             int last_dc_val, c_derived_tbl *dctbl,
1115                             c_derived_tbl *actbl)
1116 {
1117   return NULL;
1118 }
1119 
1120 GLOBAL(int)
jsimd_can_encode_mcu_AC_first_prepare(void)1121 jsimd_can_encode_mcu_AC_first_prepare(void)
1122 {
1123   return 0;
1124 }
1125 
1126 GLOBAL(void)
jsimd_encode_mcu_AC_first_prepare(const JCOEF * block,const int * jpeg_natural_order_start,int Sl,int Al,JCOEF * values,size_t * zerobits)1127 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
1128                                   const int *jpeg_natural_order_start, int Sl,
1129                                   int Al, JCOEF *values, size_t *zerobits)
1130 {
1131 }
1132 
1133 GLOBAL(int)
jsimd_can_encode_mcu_AC_refine_prepare(void)1134 jsimd_can_encode_mcu_AC_refine_prepare(void)
1135 {
1136   return 0;
1137 }
1138 
1139 GLOBAL(int)
jsimd_encode_mcu_AC_refine_prepare(const JCOEF * block,const int * jpeg_natural_order_start,int Sl,int Al,JCOEF * absvalues,size_t * bits)1140 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
1141                                    const int *jpeg_natural_order_start, int Sl,
1142                                    int Al, JCOEF *absvalues, size_t *bits)
1143 {
1144   return 0;
1145 }
1146