Imported Upstream version 3.0.1
[platform/upstream/libjpeg-turbo.git] / simd / arm / aarch32 / jsimd.c
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, 2022, 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 THREAD_LOCAL unsigned int simd_support = ~0;
31 static THREAD_LOCAL 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)
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)
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 LOCAL(void)
101 init_simd(void)
102 {
103 #ifndef NO_GETENV
104   char env[2] = { 0 };
105 #endif
106 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
107   int bufsize = 1024; /* an initial guess for the line buffer size limit */
108 #endif
109
110   if (simd_support != ~0U)
111     return;
112
113   simd_support = 0;
114
115 #if defined(__ARM_NEON__)
116   simd_support |= JSIMD_NEON;
117 #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
118   /* We still have a chance to use Neon regardless of globally used
119    * -mcpu/-mfpu options passed to gcc by performing runtime detection via
120    * /proc/cpuinfo parsing on linux/android */
121   while (!parse_proc_cpuinfo(bufsize)) {
122     bufsize *= 2;
123     if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
124       break;
125   }
126 #endif
127
128 #ifndef NO_GETENV
129   /* Force different settings through environment variables */
130   if (!GETENV_S(env, 2, "JSIMD_FORCENEON") && !strcmp(env, "1"))
131     simd_support = JSIMD_NEON;
132   if (!GETENV_S(env, 2, "JSIMD_FORCENONE") && !strcmp(env, "1"))
133     simd_support = 0;
134   if (!GETENV_S(env, 2, "JSIMD_NOHUFFENC") && !strcmp(env, "1"))
135     simd_huffman = 0;
136 #endif
137 }
138
139 GLOBAL(int)
140 jsimd_can_rgb_ycc(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_NEON)
153     return 1;
154
155   return 0;
156 }
157
158 GLOBAL(int)
159 jsimd_can_rgb_gray(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_NEON)
172     return 1;
173
174   return 0;
175 }
176
177 GLOBAL(int)
178 jsimd_can_ycc_rgb(void)
179 {
180   init_simd();
181
182   /* The code is optimised for these values only */
183   if (BITS_IN_JSAMPLE != 8)
184     return 0;
185   if (sizeof(JDIMENSION) != 4)
186     return 0;
187   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
188     return 0;
189
190   if (simd_support & JSIMD_NEON)
191     return 1;
192
193   return 0;
194 }
195
196 GLOBAL(int)
197 jsimd_can_ycc_rgb565(void)
198 {
199   init_simd();
200
201   /* The code is optimised for these values only */
202   if (BITS_IN_JSAMPLE != 8)
203     return 0;
204   if (sizeof(JDIMENSION) != 4)
205     return 0;
206
207   if (simd_support & JSIMD_NEON)
208     return 1;
209
210   return 0;
211 }
212
213 GLOBAL(void)
214 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
215                       JSAMPIMAGE output_buf, JDIMENSION output_row,
216                       int num_rows)
217 {
218   void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
219
220   switch (cinfo->in_color_space) {
221   case JCS_EXT_RGB:
222     neonfct = jsimd_extrgb_ycc_convert_neon;
223     break;
224   case JCS_EXT_RGBX:
225   case JCS_EXT_RGBA:
226     neonfct = jsimd_extrgbx_ycc_convert_neon;
227     break;
228   case JCS_EXT_BGR:
229     neonfct = jsimd_extbgr_ycc_convert_neon;
230     break;
231   case JCS_EXT_BGRX:
232   case JCS_EXT_BGRA:
233     neonfct = jsimd_extbgrx_ycc_convert_neon;
234     break;
235   case JCS_EXT_XBGR:
236   case JCS_EXT_ABGR:
237     neonfct = jsimd_extxbgr_ycc_convert_neon;
238     break;
239   case JCS_EXT_XRGB:
240   case JCS_EXT_ARGB:
241     neonfct = jsimd_extxrgb_ycc_convert_neon;
242     break;
243   default:
244     neonfct = jsimd_extrgb_ycc_convert_neon;
245     break;
246   }
247
248   neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
249 }
250
251 GLOBAL(void)
252 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
253                        JSAMPIMAGE output_buf, JDIMENSION output_row,
254                        int num_rows)
255 {
256   void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
257
258   switch (cinfo->in_color_space) {
259   case JCS_EXT_RGB:
260     neonfct = jsimd_extrgb_gray_convert_neon;
261     break;
262   case JCS_EXT_RGBX:
263   case JCS_EXT_RGBA:
264     neonfct = jsimd_extrgbx_gray_convert_neon;
265     break;
266   case JCS_EXT_BGR:
267     neonfct = jsimd_extbgr_gray_convert_neon;
268     break;
269   case JCS_EXT_BGRX:
270   case JCS_EXT_BGRA:
271     neonfct = jsimd_extbgrx_gray_convert_neon;
272     break;
273   case JCS_EXT_XBGR:
274   case JCS_EXT_ABGR:
275     neonfct = jsimd_extxbgr_gray_convert_neon;
276     break;
277   case JCS_EXT_XRGB:
278   case JCS_EXT_ARGB:
279     neonfct = jsimd_extxrgb_gray_convert_neon;
280     break;
281   default:
282     neonfct = jsimd_extrgb_gray_convert_neon;
283     break;
284   }
285
286   neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
287 }
288
289 GLOBAL(void)
290 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
291                       JDIMENSION input_row, JSAMPARRAY output_buf,
292                       int num_rows)
293 {
294   void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
295
296   switch (cinfo->out_color_space) {
297   case JCS_EXT_RGB:
298     neonfct = jsimd_ycc_extrgb_convert_neon;
299     break;
300   case JCS_EXT_RGBX:
301   case JCS_EXT_RGBA:
302     neonfct = jsimd_ycc_extrgbx_convert_neon;
303     break;
304   case JCS_EXT_BGR:
305     neonfct = jsimd_ycc_extbgr_convert_neon;
306     break;
307   case JCS_EXT_BGRX:
308   case JCS_EXT_BGRA:
309     neonfct = jsimd_ycc_extbgrx_convert_neon;
310     break;
311   case JCS_EXT_XBGR:
312   case JCS_EXT_ABGR:
313     neonfct = jsimd_ycc_extxbgr_convert_neon;
314     break;
315   case JCS_EXT_XRGB:
316   case JCS_EXT_ARGB:
317     neonfct = jsimd_ycc_extxrgb_convert_neon;
318     break;
319   default:
320     neonfct = jsimd_ycc_extrgb_convert_neon;
321     break;
322   }
323
324   neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
325 }
326
327 GLOBAL(void)
328 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
329                          JDIMENSION input_row, JSAMPARRAY output_buf,
330                          int num_rows)
331 {
332   jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
333                                 output_buf, num_rows);
334 }
335
336 GLOBAL(int)
337 jsimd_can_h2v2_downsample(void)
338 {
339   init_simd();
340
341   /* The code is optimised for these values only */
342   if (BITS_IN_JSAMPLE != 8)
343     return 0;
344   if (DCTSIZE != 8)
345     return 0;
346   if (sizeof(JDIMENSION) != 4)
347     return 0;
348
349   if (simd_support & JSIMD_NEON)
350     return 1;
351
352   return 0;
353 }
354
355 GLOBAL(int)
356 jsimd_can_h2v1_downsample(void)
357 {
358   init_simd();
359
360   /* The code is optimised for these values only */
361   if (BITS_IN_JSAMPLE != 8)
362     return 0;
363   if (DCTSIZE != 8)
364     return 0;
365   if (sizeof(JDIMENSION) != 4)
366     return 0;
367
368   if (simd_support & JSIMD_NEON)
369     return 1;
370
371   return 0;
372 }
373
374 GLOBAL(void)
375 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
376                       JSAMPARRAY input_data, JSAMPARRAY output_data)
377 {
378   jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
379                              compptr->v_samp_factor, compptr->width_in_blocks,
380                              input_data, output_data);
381 }
382
383 GLOBAL(void)
384 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
385                       JSAMPARRAY input_data, JSAMPARRAY output_data)
386 {
387   jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
388                              compptr->v_samp_factor, compptr->width_in_blocks,
389                              input_data, output_data);
390 }
391
392 GLOBAL(int)
393 jsimd_can_h2v2_upsample(void)
394 {
395   init_simd();
396
397   /* The code is optimised for these values only */
398   if (BITS_IN_JSAMPLE != 8)
399     return 0;
400   if (sizeof(JDIMENSION) != 4)
401     return 0;
402
403   if (simd_support & JSIMD_NEON)
404     return 1;
405
406   return 0;
407 }
408
409 GLOBAL(int)
410 jsimd_can_h2v1_upsample(void)
411 {
412   init_simd();
413
414   /* The code is optimised for these values only */
415   if (BITS_IN_JSAMPLE != 8)
416     return 0;
417   if (sizeof(JDIMENSION) != 4)
418     return 0;
419   if (simd_support & JSIMD_NEON)
420     return 1;
421
422   return 0;
423 }
424
425 GLOBAL(void)
426 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
427                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
428 {
429   jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
430                            input_data, output_data_ptr);
431 }
432
433 GLOBAL(void)
434 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
435                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
436 {
437   jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
438                            input_data, output_data_ptr);
439 }
440
441 GLOBAL(int)
442 jsimd_can_h2v2_fancy_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 (simd_support & JSIMD_NEON)
453     return 1;
454
455   return 0;
456 }
457
458 GLOBAL(int)
459 jsimd_can_h2v1_fancy_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_NEON)
470     return 1;
471
472   return 0;
473 }
474
475 GLOBAL(int)
476 jsimd_can_h1v2_fancy_upsample(void)
477 {
478   init_simd();
479
480   /* The code is optimised for these values only */
481   if (BITS_IN_JSAMPLE != 8)
482     return 0;
483   if (sizeof(JDIMENSION) != 4)
484     return 0;
485
486   if (simd_support & JSIMD_NEON)
487     return 1;
488
489   return 0;
490 }
491
492 GLOBAL(void)
493 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
494                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
495 {
496   jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
497                                  compptr->downsampled_width, input_data,
498                                  output_data_ptr);
499 }
500
501 GLOBAL(void)
502 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
503                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
504 {
505   jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
506                                  compptr->downsampled_width, input_data,
507                                  output_data_ptr);
508 }
509
510 GLOBAL(void)
511 jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
512                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
513 {
514   jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
515                                  compptr->downsampled_width, input_data,
516                                  output_data_ptr);
517 }
518
519 GLOBAL(int)
520 jsimd_can_h2v2_merged_upsample(void)
521 {
522   init_simd();
523
524   /* The code is optimised for these values only */
525   if (BITS_IN_JSAMPLE != 8)
526     return 0;
527   if (sizeof(JDIMENSION) != 4)
528     return 0;
529
530   if (simd_support & JSIMD_NEON)
531     return 1;
532
533   return 0;
534 }
535
536 GLOBAL(int)
537 jsimd_can_h2v1_merged_upsample(void)
538 {
539   init_simd();
540
541   /* The code is optimised for these values only */
542   if (BITS_IN_JSAMPLE != 8)
543     return 0;
544   if (sizeof(JDIMENSION) != 4)
545     return 0;
546
547   if (simd_support & JSIMD_NEON)
548     return 1;
549
550   return 0;
551 }
552
553 GLOBAL(void)
554 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
555                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
556 {
557   void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
558
559   switch (cinfo->out_color_space) {
560     case JCS_EXT_RGB:
561       neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
562       break;
563     case JCS_EXT_RGBX:
564     case JCS_EXT_RGBA:
565       neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon;
566       break;
567     case JCS_EXT_BGR:
568       neonfct = jsimd_h2v2_extbgr_merged_upsample_neon;
569       break;
570     case JCS_EXT_BGRX:
571     case JCS_EXT_BGRA:
572       neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon;
573       break;
574     case JCS_EXT_XBGR:
575     case JCS_EXT_ABGR:
576       neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon;
577       break;
578     case JCS_EXT_XRGB:
579     case JCS_EXT_ARGB:
580       neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon;
581       break;
582     default:
583       neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
584       break;
585   }
586
587   neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
588 }
589
590 GLOBAL(void)
591 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
592                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
593 {
594   void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
595
596   switch (cinfo->out_color_space) {
597     case JCS_EXT_RGB:
598       neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
599       break;
600     case JCS_EXT_RGBX:
601     case JCS_EXT_RGBA:
602       neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon;
603       break;
604     case JCS_EXT_BGR:
605       neonfct = jsimd_h2v1_extbgr_merged_upsample_neon;
606       break;
607     case JCS_EXT_BGRX:
608     case JCS_EXT_BGRA:
609       neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon;
610       break;
611     case JCS_EXT_XBGR:
612     case JCS_EXT_ABGR:
613       neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon;
614       break;
615     case JCS_EXT_XRGB:
616     case JCS_EXT_ARGB:
617       neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon;
618       break;
619     default:
620       neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
621       break;
622   }
623
624   neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
625 }
626
627 GLOBAL(int)
628 jsimd_can_convsamp(void)
629 {
630   init_simd();
631
632   /* The code is optimised for these values only */
633   if (DCTSIZE != 8)
634     return 0;
635   if (BITS_IN_JSAMPLE != 8)
636     return 0;
637   if (sizeof(JDIMENSION) != 4)
638     return 0;
639   if (sizeof(DCTELEM) != 2)
640     return 0;
641
642   if (simd_support & JSIMD_NEON)
643     return 1;
644
645   return 0;
646 }
647
648 GLOBAL(int)
649 jsimd_can_convsamp_float(void)
650 {
651   return 0;
652 }
653
654 GLOBAL(void)
655 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
656                DCTELEM *workspace)
657 {
658   jsimd_convsamp_neon(sample_data, start_col, workspace);
659 }
660
661 GLOBAL(void)
662 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
663                      FAST_FLOAT *workspace)
664 {
665 }
666
667 GLOBAL(int)
668 jsimd_can_fdct_islow(void)
669 {
670   init_simd();
671
672   /* The code is optimised for these values only */
673   if (DCTSIZE != 8)
674     return 0;
675   if (sizeof(DCTELEM) != 2)
676     return 0;
677
678   if (simd_support & JSIMD_NEON)
679     return 1;
680
681   return 0;
682 }
683
684 GLOBAL(int)
685 jsimd_can_fdct_ifast(void)
686 {
687   init_simd();
688
689   /* The code is optimised for these values only */
690   if (DCTSIZE != 8)
691     return 0;
692   if (sizeof(DCTELEM) != 2)
693     return 0;
694
695   if (simd_support & JSIMD_NEON)
696     return 1;
697
698   return 0;
699 }
700
701 GLOBAL(int)
702 jsimd_can_fdct_float(void)
703 {
704   return 0;
705 }
706
707 GLOBAL(void)
708 jsimd_fdct_islow(DCTELEM *data)
709 {
710   jsimd_fdct_islow_neon(data);
711 }
712
713 GLOBAL(void)
714 jsimd_fdct_ifast(DCTELEM *data)
715 {
716   jsimd_fdct_ifast_neon(data);
717 }
718
719 GLOBAL(void)
720 jsimd_fdct_float(FAST_FLOAT *data)
721 {
722 }
723
724 GLOBAL(int)
725 jsimd_can_quantize(void)
726 {
727   init_simd();
728
729   /* The code is optimised for these values only */
730   if (DCTSIZE != 8)
731     return 0;
732   if (sizeof(JCOEF) != 2)
733     return 0;
734   if (sizeof(DCTELEM) != 2)
735     return 0;
736
737   if (simd_support & JSIMD_NEON)
738     return 1;
739
740   return 0;
741 }
742
743 GLOBAL(int)
744 jsimd_can_quantize_float(void)
745 {
746   return 0;
747 }
748
749 GLOBAL(void)
750 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
751 {
752   jsimd_quantize_neon(coef_block, divisors, workspace);
753 }
754
755 GLOBAL(void)
756 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
757                      FAST_FLOAT *workspace)
758 {
759 }
760
761 GLOBAL(int)
762 jsimd_can_idct_2x2(void)
763 {
764   init_simd();
765
766   /* The code is optimised for these values only */
767   if (DCTSIZE != 8)
768     return 0;
769   if (sizeof(JCOEF) != 2)
770     return 0;
771   if (BITS_IN_JSAMPLE != 8)
772     return 0;
773   if (sizeof(JDIMENSION) != 4)
774     return 0;
775   if (sizeof(ISLOW_MULT_TYPE) != 2)
776     return 0;
777
778   if (simd_support & JSIMD_NEON)
779     return 1;
780
781   return 0;
782 }
783
784 GLOBAL(int)
785 jsimd_can_idct_4x4(void)
786 {
787   init_simd();
788
789   /* The code is optimised for these values only */
790   if (DCTSIZE != 8)
791     return 0;
792   if (sizeof(JCOEF) != 2)
793     return 0;
794   if (BITS_IN_JSAMPLE != 8)
795     return 0;
796   if (sizeof(JDIMENSION) != 4)
797     return 0;
798   if (sizeof(ISLOW_MULT_TYPE) != 2)
799     return 0;
800
801   if (simd_support & JSIMD_NEON)
802     return 1;
803
804   return 0;
805 }
806
807 GLOBAL(void)
808 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
809                JCOEFPTR coef_block, JSAMPARRAY output_buf,
810                JDIMENSION output_col)
811 {
812   jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
813 }
814
815 GLOBAL(void)
816 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
817                JCOEFPTR coef_block, JSAMPARRAY output_buf,
818                JDIMENSION output_col)
819 {
820   jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
821 }
822
823 GLOBAL(int)
824 jsimd_can_idct_islow(void)
825 {
826   init_simd();
827
828   /* The code is optimised for these values only */
829   if (DCTSIZE != 8)
830     return 0;
831   if (sizeof(JCOEF) != 2)
832     return 0;
833   if (BITS_IN_JSAMPLE != 8)
834     return 0;
835   if (sizeof(JDIMENSION) != 4)
836     return 0;
837   if (sizeof(ISLOW_MULT_TYPE) != 2)
838     return 0;
839
840   if (simd_support & JSIMD_NEON)
841     return 1;
842
843   return 0;
844 }
845
846 GLOBAL(int)
847 jsimd_can_idct_ifast(void)
848 {
849   init_simd();
850
851   /* The code is optimised for these values only */
852   if (DCTSIZE != 8)
853     return 0;
854   if (sizeof(JCOEF) != 2)
855     return 0;
856   if (BITS_IN_JSAMPLE != 8)
857     return 0;
858   if (sizeof(JDIMENSION) != 4)
859     return 0;
860   if (sizeof(IFAST_MULT_TYPE) != 2)
861     return 0;
862   if (IFAST_SCALE_BITS != 2)
863     return 0;
864
865   if (simd_support & JSIMD_NEON)
866     return 1;
867
868   return 0;
869 }
870
871 GLOBAL(int)
872 jsimd_can_idct_float(void)
873 {
874   return 0;
875 }
876
877 GLOBAL(void)
878 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
879                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
880                  JDIMENSION output_col)
881 {
882   jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
883                         output_col);
884 }
885
886 GLOBAL(void)
887 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
888                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
889                  JDIMENSION output_col)
890 {
891   jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
892                         output_col);
893 }
894
895 GLOBAL(void)
896 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
897                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
898                  JDIMENSION output_col)
899 {
900 }
901
902 GLOBAL(int)
903 jsimd_can_huff_encode_one_block(void)
904 {
905   init_simd();
906
907   if (DCTSIZE != 8)
908     return 0;
909   if (sizeof(JCOEF) != 2)
910     return 0;
911
912   if (simd_support & JSIMD_NEON && simd_huffman)
913     return 1;
914
915   return 0;
916 }
917
918 GLOBAL(JOCTET *)
919 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
920                             int last_dc_val, c_derived_tbl *dctbl,
921                             c_derived_tbl *actbl)
922 {
923   return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
924                                           dctbl, actbl);
925 }
926
927 GLOBAL(int)
928 jsimd_can_encode_mcu_AC_first_prepare(void)
929 {
930   init_simd();
931
932   if (DCTSIZE != 8)
933     return 0;
934   if (sizeof(JCOEF) != 2)
935     return 0;
936
937   if (simd_support & JSIMD_NEON)
938     return 1;
939
940   return 0;
941 }
942
943 GLOBAL(void)
944 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
945                                   const int *jpeg_natural_order_start, int Sl,
946                                   int Al, UJCOEF *values, size_t *zerobits)
947 {
948   jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start,
949                                          Sl, Al, values, zerobits);
950 }
951
952 GLOBAL(int)
953 jsimd_can_encode_mcu_AC_refine_prepare(void)
954 {
955   init_simd();
956
957   if (DCTSIZE != 8)
958     return 0;
959   if (sizeof(JCOEF) != 2)
960     return 0;
961
962   if (simd_support & JSIMD_NEON)
963     return 1;
964
965   return 0;
966 }
967
968 GLOBAL(int)
969 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
970                                    const int *jpeg_natural_order_start, int Sl,
971                                    int Al, UJCOEF *absvalues, size_t *bits)
972 {
973   return jsimd_encode_mcu_AC_refine_prepare_neon(block,
974                                                  jpeg_natural_order_start, Sl,
975                                                  Al, absvalues, bits);
976 }