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