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