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