36ea865d41e493ae472ead4e057aee5e86f1556a
[platform/upstream/libjpeg-turbo.git] / simd / mips / jsimd.c
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)
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)
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)
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)
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)
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)
176 jsimd_can_ycc_rgb565(void)
177 {
178   return 0;
179 }
180
181 GLOBAL(int)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
772 jsimd_can_fdct_float(void)
773 {
774   return 0;
775 }
776
777 GLOBAL(void)
778 jsimd_fdct_islow(DCTELEM *data)
779 {
780   jsimd_fdct_islow_dspr2(data);
781 }
782
783 GLOBAL(void)
784 jsimd_fdct_ifast(DCTELEM *data)
785 {
786   jsimd_fdct_ifast_dspr2(data);
787 }
788
789 GLOBAL(void)
790 jsimd_fdct_float(FAST_FLOAT *data)
791 {
792 }
793
794 GLOBAL(int)
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)
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)
839 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
840 {
841   jsimd_quantize_dspr2(coef_block, divisors, workspace);
842 }
843
844 GLOBAL(void)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
1049 jsimd_can_idct_float(void)
1050 {
1051   return 0;
1052 }
1053
1054 GLOBAL(void)
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)
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)
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)
1107 jsimd_can_huff_encode_one_block(void)
1108 {
1109   return 0;
1110 }
1111
1112 GLOBAL(JOCTET *)
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)
1121 jsimd_can_encode_mcu_AC_first_prepare(void)
1122 {
1123   return 0;
1124 }
1125
1126 GLOBAL(void)
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)
1134 jsimd_can_encode_mcu_AC_refine_prepare(void)
1135 {
1136   return 0;
1137 }
1138
1139 GLOBAL(int)
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 }