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