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
29static unsigned int simd_support = ~0;
30
31#if defined(__linux__)
32
33LOCAL(int)
34parse_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 */
62LOCAL(void)
63init_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
81static 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 */
89typedef void (*upsample1_ptr) (j_decompress_ptr cinfo,
90                               jpeg_component_info * compptr,
91                               JSAMPARRAY input_data,
92                               JSAMPARRAY * output_data_ptr);
93
94typedef 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
105typedef my_upsampler * my_upsample_ptr;
106
107GLOBAL(int)
108jsimd_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
126GLOBAL(int)
127jsimd_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
145GLOBAL(int)
146jsimd_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
164GLOBAL(int)
165jsimd_can_ycc_rgb565 (void)
166{
167  return 0;
168}
169
170GLOBAL(int)
171jsimd_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
187GLOBAL(void)
188jsimd_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
228GLOBAL(void)
229jsimd_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
268GLOBAL(void)
269jsimd_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
308GLOBAL(void)
309jsimd_ycc_rgb565_convert (j_decompress_ptr cinfo,
310                          JSAMPIMAGE input_buf, JDIMENSION input_row,
311                          JSAMPARRAY output_buf, int num_rows)
312{
313}
314
315GLOBAL(void)
316jsimd_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
326GLOBAL(int)
327jsimd_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
343GLOBAL(int)
344jsimd_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
362GLOBAL(int)
363jsimd_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
379GLOBAL(void)
380jsimd_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
391GLOBAL(void)
392jsimd_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
404GLOBAL(void)
405jsimd_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
416GLOBAL(int)
417jsimd_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
433GLOBAL(int)
434jsimd_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
450GLOBAL(int)
451jsimd_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
467GLOBAL(void)
468jsimd_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
479GLOBAL(void)
480jsimd_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
491GLOBAL(void)
492jsimd_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
504GLOBAL(int)
505jsimd_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
521GLOBAL(int)
522jsimd_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
538GLOBAL(void)
539jsimd_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
550GLOBAL(void)
551jsimd_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
562GLOBAL(int)
563jsimd_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
578GLOBAL(int)
579jsimd_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
594GLOBAL(void)
595jsimd_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
635GLOBAL(void)
636jsimd_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
676GLOBAL(int)
677jsimd_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
697GLOBAL(int)
698jsimd_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
720GLOBAL(void)
721jsimd_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
728GLOBAL(void)
729jsimd_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
736GLOBAL(int)
737jsimd_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
753GLOBAL(int)
754jsimd_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
770GLOBAL(int)
771jsimd_can_fdct_float (void)
772{
773  init_simd();
774
775  return 0;
776}
777
778GLOBAL(void)
779jsimd_fdct_islow (DCTELEM * data)
780{
781  if (simd_support & JSIMD_MIPS_DSPR2)
782    jsimd_fdct_islow_mips_dspr2(data);
783}
784
785GLOBAL(void)
786jsimd_fdct_ifast (DCTELEM * data)
787{
788  if (simd_support & JSIMD_MIPS_DSPR2)
789    jsimd_fdct_ifast_mips_dspr2(data);
790}
791
792GLOBAL(void)
793jsimd_fdct_float (FAST_FLOAT * data)
794{
795}
796
797GLOBAL(int)
798jsimd_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
816GLOBAL(int)
817jsimd_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
839GLOBAL(void)
840jsimd_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
847GLOBAL(void)
848jsimd_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
855GLOBAL(int)
856jsimd_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
878GLOBAL(int)
879jsimd_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
901GLOBAL(int)
902jsimd_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
924GLOBAL(int)
925jsimd_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
946GLOBAL(void)
947jsimd_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
956GLOBAL(void)
957jsimd_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
968GLOBAL(void)
969jsimd_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
978GLOBAL(void)
979jsimd_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
1005GLOBAL(int)
1006jsimd_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
1028GLOBAL(int)
1029jsimd_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
1053GLOBAL(int)
1054jsimd_can_idct_float (void)
1055{
1056  init_simd();
1057
1058  return 0;
1059}
1060
1061GLOBAL(void)
1062jsimd_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
1083GLOBAL(void)
1084jsimd_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
1110GLOBAL(void)
1111jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
1112                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1113                  JDIMENSION output_col)
1114{
1115}
1116