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