1 /*
2 * jsimd_arm.c
3 *
4 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5 * Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
6 * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2022, D. R. Commander.
7 * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
8 * Copyright (C) 2019, Google LLC.
9 * Copyright (C) 2020, Arm Limited.
10 *
11 * Based on the x86 SIMD extension for IJG JPEG library,
12 * Copyright (C) 1999-2006, MIYASAKA Masaru.
13 * For conditions of distribution and use, see copyright notice in jsimdext.inc
14 *
15 * This file contains the interface between the "normal" portions
16 * of the library and the SIMD implementations when running on a
17 * 32-bit Arm architecture.
18 */
19
20 #define JPEG_INTERNALS
21 #include "../../../jinclude.h"
22 #include "../../../jpeglib.h"
23 #include "../../../jsimd.h"
24 #include "../../../jdct.h"
25 #include "../../../jsimddct.h"
26 #include "../../jsimd.h"
27
28 #include <ctype.h>
29
30 static unsigned int simd_support = ~0;
31 static unsigned int simd_huffman = 1;
32
33 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
34
35 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
36
37 LOCAL(int)
check_feature(char * buffer,char * feature)38 check_feature(char *buffer, char *feature)
39 {
40 char *p;
41
42 if (*feature == 0)
43 return 0;
44 if (strncmp(buffer, "Features", 8) != 0)
45 return 0;
46 buffer += 8;
47 while (isspace(*buffer))
48 buffer++;
49
50 /* Check if 'feature' is present in the buffer as a separate word */
51 while ((p = strstr(buffer, feature))) {
52 if (p > buffer && !isspace(*(p - 1))) {
53 buffer++;
54 continue;
55 }
56 p += strlen(feature);
57 if (*p != 0 && !isspace(*p)) {
58 buffer++;
59 continue;
60 }
61 return 1;
62 }
63 return 0;
64 }
65
66 LOCAL(int)
parse_proc_cpuinfo(int bufsize)67 parse_proc_cpuinfo(int bufsize)
68 {
69 char *buffer = (char *)malloc(bufsize);
70 FILE *fd;
71
72 simd_support = 0;
73
74 if (!buffer)
75 return 0;
76
77 fd = fopen("/proc/cpuinfo", "r");
78 if (fd) {
79 while (fgets(buffer, bufsize, fd)) {
80 if (!strchr(buffer, '\n') && !feof(fd)) {
81 /* "impossible" happened - insufficient size of the buffer! */
82 fclose(fd);
83 free(buffer);
84 return 0;
85 }
86 if (check_feature(buffer, "neon"))
87 simd_support |= JSIMD_NEON;
88 }
89 fclose(fd);
90 }
91 free(buffer);
92 return 1;
93 }
94
95 #endif
96
97 /*
98 * Check what SIMD accelerations are supported.
99 *
100 * FIXME: This code is racy under a multi-threaded environment.
101 */
102 LOCAL(void)
init_simd(void)103 init_simd(void)
104 {
105 #ifndef NO_GETENV
106 char env[2] = { 0 };
107 #endif
108 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
109 int bufsize = 1024; /* an initial guess for the line buffer size limit */
110 #endif
111
112 if (simd_support != ~0U)
113 return;
114
115 simd_support = 0;
116
117 #if defined(__ARM_NEON__)
118 simd_support |= JSIMD_NEON;
119 #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
120 /* We still have a chance to use Neon regardless of globally used
121 * -mcpu/-mfpu options passed to gcc by performing runtime detection via
122 * /proc/cpuinfo parsing on linux/android */
123 while (!parse_proc_cpuinfo(bufsize)) {
124 bufsize *= 2;
125 if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
126 break;
127 }
128 #endif
129
130 #ifndef NO_GETENV
131 /* Force different settings through environment variables */
132 if (!GETENV_S(env, 2, "JSIMD_FORCENEON") && !strcmp(env, "1"))
133 simd_support = JSIMD_NEON;
134 if (!GETENV_S(env, 2, "JSIMD_FORCENONE") && !strcmp(env, "1"))
135 simd_support = 0;
136 if (!GETENV_S(env, 2, "JSIMD_NOHUFFENC") && !strcmp(env, "1"))
137 simd_huffman = 0;
138 #endif
139 }
140
141 GLOBAL(int)
jsimd_can_rgb_ycc(void)142 jsimd_can_rgb_ycc(void)
143 {
144 init_simd();
145
146 /* The code is optimised for these values only */
147 if (BITS_IN_JSAMPLE != 8)
148 return 0;
149 if (sizeof(JDIMENSION) != 4)
150 return 0;
151 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
152 return 0;
153
154 if (simd_support & JSIMD_NEON)
155 return 1;
156
157 return 0;
158 }
159
160 GLOBAL(int)
jsimd_can_rgb_gray(void)161 jsimd_can_rgb_gray(void)
162 {
163 init_simd();
164
165 /* The code is optimised for these values only */
166 if (BITS_IN_JSAMPLE != 8)
167 return 0;
168 if (sizeof(JDIMENSION) != 4)
169 return 0;
170 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
171 return 0;
172
173 if (simd_support & JSIMD_NEON)
174 return 1;
175
176 return 0;
177 }
178
179 GLOBAL(int)
jsimd_can_ycc_rgb(void)180 jsimd_can_ycc_rgb(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 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
190 return 0;
191
192 if (simd_support & JSIMD_NEON)
193 return 1;
194
195 return 0;
196 }
197
198 GLOBAL(int)
jsimd_can_ycc_rgb565(void)199 jsimd_can_ycc_rgb565(void)
200 {
201 init_simd();
202
203 /* The code is optimised for these values only */
204 if (BITS_IN_JSAMPLE != 8)
205 return 0;
206 if (sizeof(JDIMENSION) != 4)
207 return 0;
208
209 if (simd_support & JSIMD_NEON)
210 return 1;
211
212 return 0;
213 }
214
215 GLOBAL(void)
jsimd_rgb_ycc_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)216 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
217 JSAMPIMAGE output_buf, JDIMENSION output_row,
218 int num_rows)
219 {
220 void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
221
222 switch (cinfo->in_color_space) {
223 case JCS_EXT_RGB:
224 neonfct = jsimd_extrgb_ycc_convert_neon;
225 break;
226 case JCS_EXT_RGBX:
227 case JCS_EXT_RGBA:
228 neonfct = jsimd_extrgbx_ycc_convert_neon;
229 break;
230 case JCS_EXT_BGR:
231 neonfct = jsimd_extbgr_ycc_convert_neon;
232 break;
233 case JCS_EXT_BGRX:
234 case JCS_EXT_BGRA:
235 neonfct = jsimd_extbgrx_ycc_convert_neon;
236 break;
237 case JCS_EXT_XBGR:
238 case JCS_EXT_ABGR:
239 neonfct = jsimd_extxbgr_ycc_convert_neon;
240 break;
241 case JCS_EXT_XRGB:
242 case JCS_EXT_ARGB:
243 neonfct = jsimd_extxrgb_ycc_convert_neon;
244 break;
245 default:
246 neonfct = jsimd_extrgb_ycc_convert_neon;
247 break;
248 }
249
250 neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
251 }
252
253 GLOBAL(void)
jsimd_rgb_gray_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)254 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
255 JSAMPIMAGE output_buf, JDIMENSION output_row,
256 int num_rows)
257 {
258 void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
259
260 switch (cinfo->in_color_space) {
261 case JCS_EXT_RGB:
262 neonfct = jsimd_extrgb_gray_convert_neon;
263 break;
264 case JCS_EXT_RGBX:
265 case JCS_EXT_RGBA:
266 neonfct = jsimd_extrgbx_gray_convert_neon;
267 break;
268 case JCS_EXT_BGR:
269 neonfct = jsimd_extbgr_gray_convert_neon;
270 break;
271 case JCS_EXT_BGRX:
272 case JCS_EXT_BGRA:
273 neonfct = jsimd_extbgrx_gray_convert_neon;
274 break;
275 case JCS_EXT_XBGR:
276 case JCS_EXT_ABGR:
277 neonfct = jsimd_extxbgr_gray_convert_neon;
278 break;
279 case JCS_EXT_XRGB:
280 case JCS_EXT_ARGB:
281 neonfct = jsimd_extxrgb_gray_convert_neon;
282 break;
283 default:
284 neonfct = jsimd_extrgb_gray_convert_neon;
285 break;
286 }
287
288 neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
289 }
290
291 GLOBAL(void)
jsimd_ycc_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)292 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
293 JDIMENSION input_row, JSAMPARRAY output_buf,
294 int num_rows)
295 {
296 void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
297
298 switch (cinfo->out_color_space) {
299 case JCS_EXT_RGB:
300 neonfct = jsimd_ycc_extrgb_convert_neon;
301 break;
302 case JCS_EXT_RGBX:
303 case JCS_EXT_RGBA:
304 neonfct = jsimd_ycc_extrgbx_convert_neon;
305 break;
306 case JCS_EXT_BGR:
307 neonfct = jsimd_ycc_extbgr_convert_neon;
308 break;
309 case JCS_EXT_BGRX:
310 case JCS_EXT_BGRA:
311 neonfct = jsimd_ycc_extbgrx_convert_neon;
312 break;
313 case JCS_EXT_XBGR:
314 case JCS_EXT_ABGR:
315 neonfct = jsimd_ycc_extxbgr_convert_neon;
316 break;
317 case JCS_EXT_XRGB:
318 case JCS_EXT_ARGB:
319 neonfct = jsimd_ycc_extxrgb_convert_neon;
320 break;
321 default:
322 neonfct = jsimd_ycc_extrgb_convert_neon;
323 break;
324 }
325
326 neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
327 }
328
329 GLOBAL(void)
jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)330 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
331 JDIMENSION input_row, JSAMPARRAY output_buf,
332 int num_rows)
333 {
334 jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
335 output_buf, num_rows);
336 }
337
338 GLOBAL(int)
jsimd_can_h2v2_downsample(void)339 jsimd_can_h2v2_downsample(void)
340 {
341 init_simd();
342
343 /* The code is optimised for these values only */
344 if (BITS_IN_JSAMPLE != 8)
345 return 0;
346 if (DCTSIZE != 8)
347 return 0;
348 if (sizeof(JDIMENSION) != 4)
349 return 0;
350
351 if (simd_support & JSIMD_NEON)
352 return 1;
353
354 return 0;
355 }
356
357 GLOBAL(int)
jsimd_can_h2v1_downsample(void)358 jsimd_can_h2v1_downsample(void)
359 {
360 init_simd();
361
362 /* The code is optimised for these values only */
363 if (BITS_IN_JSAMPLE != 8)
364 return 0;
365 if (DCTSIZE != 8)
366 return 0;
367 if (sizeof(JDIMENSION) != 4)
368 return 0;
369
370 if (simd_support & JSIMD_NEON)
371 return 1;
372
373 return 0;
374 }
375
376 GLOBAL(void)
jsimd_h2v2_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)377 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
378 JSAMPARRAY input_data, JSAMPARRAY output_data)
379 {
380 jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
381 compptr->v_samp_factor, compptr->width_in_blocks,
382 input_data, output_data);
383 }
384
385 GLOBAL(void)
jsimd_h2v1_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)386 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
387 JSAMPARRAY input_data, JSAMPARRAY output_data)
388 {
389 jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
390 compptr->v_samp_factor, compptr->width_in_blocks,
391 input_data, output_data);
392 }
393
394 GLOBAL(int)
jsimd_can_h2v2_upsample(void)395 jsimd_can_h2v2_upsample(void)
396 {
397 init_simd();
398
399 /* The code is optimised for these values only */
400 if (BITS_IN_JSAMPLE != 8)
401 return 0;
402 if (sizeof(JDIMENSION) != 4)
403 return 0;
404
405 if (simd_support & JSIMD_NEON)
406 return 1;
407
408 return 0;
409 }
410
411 GLOBAL(int)
jsimd_can_h2v1_upsample(void)412 jsimd_can_h2v1_upsample(void)
413 {
414 init_simd();
415
416 /* The code is optimised for these values only */
417 if (BITS_IN_JSAMPLE != 8)
418 return 0;
419 if (sizeof(JDIMENSION) != 4)
420 return 0;
421 if (simd_support & JSIMD_NEON)
422 return 1;
423
424 return 0;
425 }
426
427 GLOBAL(void)
jsimd_h2v2_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)428 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
429 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
430 {
431 jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
432 input_data, output_data_ptr);
433 }
434
435 GLOBAL(void)
jsimd_h2v1_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)436 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
437 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
438 {
439 jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
440 input_data, output_data_ptr);
441 }
442
443 GLOBAL(int)
jsimd_can_h2v2_fancy_upsample(void)444 jsimd_can_h2v2_fancy_upsample(void)
445 {
446 init_simd();
447
448 /* The code is optimised for these values only */
449 if (BITS_IN_JSAMPLE != 8)
450 return 0;
451 if (sizeof(JDIMENSION) != 4)
452 return 0;
453
454 if (simd_support & JSIMD_NEON)
455 return 1;
456
457 return 0;
458 }
459
460 GLOBAL(int)
jsimd_can_h2v1_fancy_upsample(void)461 jsimd_can_h2v1_fancy_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_NEON)
472 return 1;
473
474 return 0;
475 }
476
477 GLOBAL(int)
jsimd_can_h1v2_fancy_upsample(void)478 jsimd_can_h1v2_fancy_upsample(void)
479 {
480 init_simd();
481
482 /* The code is optimised for these values only */
483 if (BITS_IN_JSAMPLE != 8)
484 return 0;
485 if (sizeof(JDIMENSION) != 4)
486 return 0;
487
488 if (simd_support & JSIMD_NEON)
489 return 1;
490
491 return 0;
492 }
493
494 GLOBAL(void)
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)495 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
496 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
497 {
498 jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
499 compptr->downsampled_width, input_data,
500 output_data_ptr);
501 }
502
503 GLOBAL(void)
jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)504 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
505 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
506 {
507 jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
508 compptr->downsampled_width, input_data,
509 output_data_ptr);
510 }
511
512 GLOBAL(void)
jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)513 jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
514 JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
515 {
516 jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
517 compptr->downsampled_width, input_data,
518 output_data_ptr);
519 }
520
521 GLOBAL(int)
jsimd_can_h2v2_merged_upsample(void)522 jsimd_can_h2v2_merged_upsample(void)
523 {
524 init_simd();
525
526 /* The code is optimised for these values only */
527 if (BITS_IN_JSAMPLE != 8)
528 return 0;
529 if (sizeof(JDIMENSION) != 4)
530 return 0;
531
532 if (simd_support & JSIMD_NEON)
533 return 1;
534
535 return 0;
536 }
537
538 GLOBAL(int)
jsimd_can_h2v1_merged_upsample(void)539 jsimd_can_h2v1_merged_upsample(void)
540 {
541 init_simd();
542
543 /* The code is optimised for these values only */
544 if (BITS_IN_JSAMPLE != 8)
545 return 0;
546 if (sizeof(JDIMENSION) != 4)
547 return 0;
548
549 if (simd_support & JSIMD_NEON)
550 return 1;
551
552 return 0;
553 }
554
555 GLOBAL(void)
jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)556 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
557 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
558 {
559 void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
560
561 switch (cinfo->out_color_space) {
562 case JCS_EXT_RGB:
563 neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
564 break;
565 case JCS_EXT_RGBX:
566 case JCS_EXT_RGBA:
567 neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon;
568 break;
569 case JCS_EXT_BGR:
570 neonfct = jsimd_h2v2_extbgr_merged_upsample_neon;
571 break;
572 case JCS_EXT_BGRX:
573 case JCS_EXT_BGRA:
574 neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon;
575 break;
576 case JCS_EXT_XBGR:
577 case JCS_EXT_ABGR:
578 neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon;
579 break;
580 case JCS_EXT_XRGB:
581 case JCS_EXT_ARGB:
582 neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon;
583 break;
584 default:
585 neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
586 break;
587 }
588
589 neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
590 }
591
592 GLOBAL(void)
jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)593 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
594 JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
595 {
596 void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
597
598 switch (cinfo->out_color_space) {
599 case JCS_EXT_RGB:
600 neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
601 break;
602 case JCS_EXT_RGBX:
603 case JCS_EXT_RGBA:
604 neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon;
605 break;
606 case JCS_EXT_BGR:
607 neonfct = jsimd_h2v1_extbgr_merged_upsample_neon;
608 break;
609 case JCS_EXT_BGRX:
610 case JCS_EXT_BGRA:
611 neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon;
612 break;
613 case JCS_EXT_XBGR:
614 case JCS_EXT_ABGR:
615 neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon;
616 break;
617 case JCS_EXT_XRGB:
618 case JCS_EXT_ARGB:
619 neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon;
620 break;
621 default:
622 neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
623 break;
624 }
625
626 neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
627 }
628
629 GLOBAL(int)
jsimd_can_convsamp(void)630 jsimd_can_convsamp(void)
631 {
632 init_simd();
633
634 /* The code is optimised for these values only */
635 if (DCTSIZE != 8)
636 return 0;
637 if (BITS_IN_JSAMPLE != 8)
638 return 0;
639 if (sizeof(JDIMENSION) != 4)
640 return 0;
641 if (sizeof(DCTELEM) != 2)
642 return 0;
643
644 if (simd_support & JSIMD_NEON)
645 return 1;
646
647 return 0;
648 }
649
650 GLOBAL(int)
jsimd_can_convsamp_float(void)651 jsimd_can_convsamp_float(void)
652 {
653 return 0;
654 }
655
656 GLOBAL(void)
jsimd_convsamp(JSAMPARRAY sample_data,JDIMENSION start_col,DCTELEM * workspace)657 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
658 DCTELEM *workspace)
659 {
660 jsimd_convsamp_neon(sample_data, start_col, workspace);
661 }
662
663 GLOBAL(void)
jsimd_convsamp_float(JSAMPARRAY sample_data,JDIMENSION start_col,FAST_FLOAT * workspace)664 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
665 FAST_FLOAT *workspace)
666 {
667 }
668
669 GLOBAL(int)
jsimd_can_fdct_islow(void)670 jsimd_can_fdct_islow(void)
671 {
672 init_simd();
673
674 /* The code is optimised for these values only */
675 if (DCTSIZE != 8)
676 return 0;
677 if (sizeof(DCTELEM) != 2)
678 return 0;
679
680 if (simd_support & JSIMD_NEON)
681 return 1;
682
683 return 0;
684 }
685
686 GLOBAL(int)
jsimd_can_fdct_ifast(void)687 jsimd_can_fdct_ifast(void)
688 {
689 init_simd();
690
691 /* The code is optimised for these values only */
692 if (DCTSIZE != 8)
693 return 0;
694 if (sizeof(DCTELEM) != 2)
695 return 0;
696
697 if (simd_support & JSIMD_NEON)
698 return 1;
699
700 return 0;
701 }
702
703 GLOBAL(int)
jsimd_can_fdct_float(void)704 jsimd_can_fdct_float(void)
705 {
706 return 0;
707 }
708
709 GLOBAL(void)
jsimd_fdct_islow(DCTELEM * data)710 jsimd_fdct_islow(DCTELEM *data)
711 {
712 jsimd_fdct_islow_neon(data);
713 }
714
715 GLOBAL(void)
jsimd_fdct_ifast(DCTELEM * data)716 jsimd_fdct_ifast(DCTELEM *data)
717 {
718 jsimd_fdct_ifast_neon(data);
719 }
720
721 GLOBAL(void)
jsimd_fdct_float(FAST_FLOAT * data)722 jsimd_fdct_float(FAST_FLOAT *data)
723 {
724 }
725
726 GLOBAL(int)
jsimd_can_quantize(void)727 jsimd_can_quantize(void)
728 {
729 init_simd();
730
731 /* The code is optimised for these values only */
732 if (DCTSIZE != 8)
733 return 0;
734 if (sizeof(JCOEF) != 2)
735 return 0;
736 if (sizeof(DCTELEM) != 2)
737 return 0;
738
739 if (simd_support & JSIMD_NEON)
740 return 1;
741
742 return 0;
743 }
744
745 GLOBAL(int)
jsimd_can_quantize_float(void)746 jsimd_can_quantize_float(void)
747 {
748 return 0;
749 }
750
751 GLOBAL(void)
jsimd_quantize(JCOEFPTR coef_block,DCTELEM * divisors,DCTELEM * workspace)752 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
753 {
754 jsimd_quantize_neon(coef_block, divisors, workspace);
755 }
756
757 GLOBAL(void)
jsimd_quantize_float(JCOEFPTR coef_block,FAST_FLOAT * divisors,FAST_FLOAT * workspace)758 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
759 FAST_FLOAT *workspace)
760 {
761 }
762
763 GLOBAL(int)
jsimd_can_idct_2x2(void)764 jsimd_can_idct_2x2(void)
765 {
766 init_simd();
767
768 /* The code is optimised for these values only */
769 if (DCTSIZE != 8)
770 return 0;
771 if (sizeof(JCOEF) != 2)
772 return 0;
773 if (BITS_IN_JSAMPLE != 8)
774 return 0;
775 if (sizeof(JDIMENSION) != 4)
776 return 0;
777 if (sizeof(ISLOW_MULT_TYPE) != 2)
778 return 0;
779
780 if (simd_support & JSIMD_NEON)
781 return 1;
782
783 return 0;
784 }
785
786 GLOBAL(int)
jsimd_can_idct_4x4(void)787 jsimd_can_idct_4x4(void)
788 {
789 init_simd();
790
791 /* The code is optimised for these values only */
792 if (DCTSIZE != 8)
793 return 0;
794 if (sizeof(JCOEF) != 2)
795 return 0;
796 if (BITS_IN_JSAMPLE != 8)
797 return 0;
798 if (sizeof(JDIMENSION) != 4)
799 return 0;
800 if (sizeof(ISLOW_MULT_TYPE) != 2)
801 return 0;
802
803 if (simd_support & JSIMD_NEON)
804 return 1;
805
806 return 0;
807 }
808
809 GLOBAL(void)
jsimd_idct_2x2(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)810 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
811 JCOEFPTR coef_block, JSAMPARRAY output_buf,
812 JDIMENSION output_col)
813 {
814 jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
815 }
816
817 GLOBAL(void)
jsimd_idct_4x4(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)818 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
819 JCOEFPTR coef_block, JSAMPARRAY output_buf,
820 JDIMENSION output_col)
821 {
822 jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
823 }
824
825 GLOBAL(int)
jsimd_can_idct_islow(void)826 jsimd_can_idct_islow(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_NEON)
843 return 1;
844
845 return 0;
846 }
847
848 GLOBAL(int)
jsimd_can_idct_ifast(void)849 jsimd_can_idct_ifast(void)
850 {
851 init_simd();
852
853 /* The code is optimised for these values only */
854 if (DCTSIZE != 8)
855 return 0;
856 if (sizeof(JCOEF) != 2)
857 return 0;
858 if (BITS_IN_JSAMPLE != 8)
859 return 0;
860 if (sizeof(JDIMENSION) != 4)
861 return 0;
862 if (sizeof(IFAST_MULT_TYPE) != 2)
863 return 0;
864 if (IFAST_SCALE_BITS != 2)
865 return 0;
866
867 if (simd_support & JSIMD_NEON)
868 return 1;
869
870 return 0;
871 }
872
873 GLOBAL(int)
jsimd_can_idct_float(void)874 jsimd_can_idct_float(void)
875 {
876 return 0;
877 }
878
879 GLOBAL(void)
jsimd_idct_islow(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)880 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
881 JCOEFPTR coef_block, JSAMPARRAY output_buf,
882 JDIMENSION output_col)
883 {
884 jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
885 output_col);
886 }
887
888 GLOBAL(void)
jsimd_idct_ifast(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)889 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
890 JCOEFPTR coef_block, JSAMPARRAY output_buf,
891 JDIMENSION output_col)
892 {
893 jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
894 output_col);
895 }
896
897 GLOBAL(void)
jsimd_idct_float(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)898 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
899 JCOEFPTR coef_block, JSAMPARRAY output_buf,
900 JDIMENSION output_col)
901 {
902 }
903
904 GLOBAL(int)
jsimd_can_huff_encode_one_block(void)905 jsimd_can_huff_encode_one_block(void)
906 {
907 init_simd();
908
909 if (DCTSIZE != 8)
910 return 0;
911 if (sizeof(JCOEF) != 2)
912 return 0;
913
914 if (simd_support & JSIMD_NEON && simd_huffman)
915 return 1;
916
917 return 0;
918 }
919
920 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)921 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
922 int last_dc_val, c_derived_tbl *dctbl,
923 c_derived_tbl *actbl)
924 {
925 return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
926 dctbl, actbl);
927 }
928
929 GLOBAL(int)
jsimd_can_encode_mcu_AC_first_prepare(void)930 jsimd_can_encode_mcu_AC_first_prepare(void)
931 {
932 init_simd();
933
934 if (DCTSIZE != 8)
935 return 0;
936 if (sizeof(JCOEF) != 2)
937 return 0;
938
939 if (simd_support & JSIMD_NEON)
940 return 1;
941
942 return 0;
943 }
944
945 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)946 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
947 const int *jpeg_natural_order_start, int Sl,
948 int Al, JCOEF *values, size_t *zerobits)
949 {
950 jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start,
951 Sl, Al, values, zerobits);
952 }
953
954 GLOBAL(int)
jsimd_can_encode_mcu_AC_refine_prepare(void)955 jsimd_can_encode_mcu_AC_refine_prepare(void)
956 {
957 init_simd();
958
959 if (DCTSIZE != 8)
960 return 0;
961 if (sizeof(JCOEF) != 2)
962 return 0;
963
964 if (simd_support & JSIMD_NEON)
965 return 1;
966
967 return 0;
968 }
969
970 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)971 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
972 const int *jpeg_natural_order_start, int Sl,
973 int Al, JCOEF *absvalues, size_t *bits)
974 {
975 return jsimd_encode_mcu_AC_refine_prepare_neon(block,
976 jpeg_natural_order_start, Sl,
977 Al, absvalues, bits);
978 }
979