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