Imported Upstream version 2.0.1
[platform/upstream/libjpeg-turbo.git] / simd / arm64 / jsimd.c
1 /*
2  * jsimd_arm64.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, D. R. Commander.
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  * 64-bit ARM architecture.
16  */
17
18 #define JPEG_INTERNALS
19 #include "../../jinclude.h"
20 #include "../../jpeglib.h"
21 #include "../../jsimd.h"
22 #include "../../jdct.h"
23 #include "../../jsimddct.h"
24 #include "../jsimd.h"
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <ctype.h>
29
30 #define JSIMD_FASTLD3  1
31 #define JSIMD_FASTST3  2
32 #define JSIMD_FASTTBL  4
33
34 static unsigned int simd_support = ~0;
35 static unsigned int simd_huffman = 1;
36 static unsigned int simd_features = JSIMD_FASTLD3 | JSIMD_FASTST3 |
37                                     JSIMD_FASTTBL;
38
39 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
40
41 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT  (1024 * 1024)
42
43 LOCAL(int)
44 check_cpuinfo(char *buffer, const char *field, char *value)
45 {
46   char *p;
47
48   if (*value == 0)
49     return 0;
50   if (strncmp(buffer, field, strlen(field)) != 0)
51     return 0;
52   buffer += strlen(field);
53   while (isspace(*buffer))
54     buffer++;
55
56   /* Check if 'value' is present in the buffer as a separate word */
57   while ((p = strstr(buffer, value))) {
58     if (p > buffer && !isspace(*(p - 1))) {
59       buffer++;
60       continue;
61     }
62     p += strlen(value);
63     if (*p != 0 && !isspace(*p)) {
64       buffer++;
65       continue;
66     }
67     return 1;
68   }
69   return 0;
70 }
71
72 LOCAL(int)
73 parse_proc_cpuinfo(int bufsize)
74 {
75   char *buffer = (char *)malloc(bufsize);
76   FILE *fd;
77
78   if (!buffer)
79     return 0;
80
81   fd = fopen("/proc/cpuinfo", "r");
82   if (fd) {
83     while (fgets(buffer, bufsize, fd)) {
84       if (!strchr(buffer, '\n') && !feof(fd)) {
85         /* "impossible" happened - insufficient size of the buffer! */
86         fclose(fd);
87         free(buffer);
88         return 0;
89       }
90       if (check_cpuinfo(buffer, "CPU part", "0xd03") ||
91           check_cpuinfo(buffer, "CPU part", "0xd07"))
92         /* The Cortex-A53 has a slow tbl implementation.  We can gain a few
93            percent speedup by disabling the use of that instruction.  The
94            speedup on Cortex-A57 is more subtle but still measurable. */
95         simd_features &= ~JSIMD_FASTTBL;
96       else if (check_cpuinfo(buffer, "CPU part", "0x0a1"))
97         /* The SIMD version of Huffman encoding is slower than the C version on
98            Cavium ThunderX.  Also, ld3 and st3 are abyssmally slow on that
99            CPU. */
100         simd_huffman = simd_features = 0;
101     }
102     fclose(fd);
103   }
104   free(buffer);
105   return 1;
106 }
107
108 #endif
109
110 /*
111  * Check what SIMD accelerations are supported.
112  *
113  * FIXME: This code is racy under a multi-threaded environment.
114  */
115
116 /*
117  * ARMv8 architectures support NEON extensions by default.
118  * It is no longer optional as it was with ARMv7.
119  */
120
121
122 LOCAL(void)
123 init_simd(void)
124 {
125 #ifndef NO_GETENV
126   char *env = NULL;
127 #endif
128 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
129   int bufsize = 1024; /* an initial guess for the line buffer size limit */
130 #endif
131
132   if (simd_support != ~0U)
133     return;
134
135   simd_support = 0;
136
137   simd_support |= JSIMD_NEON;
138 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
139   while (!parse_proc_cpuinfo(bufsize)) {
140     bufsize *= 2;
141     if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
142       break;
143   }
144 #endif
145
146 #ifndef NO_GETENV
147   /* Force different settings through environment variables */
148   env = getenv("JSIMD_FORCENEON");
149   if ((env != NULL) && (strcmp(env, "1") == 0))
150     simd_support = JSIMD_NEON;
151   env = getenv("JSIMD_FORCENONE");
152   if ((env != NULL) && (strcmp(env, "1") == 0))
153     simd_support = 0;
154   env = getenv("JSIMD_NOHUFFENC");
155   if ((env != NULL) && (strcmp(env, "1") == 0))
156     simd_huffman = 0;
157   env = getenv("JSIMD_FASTLD3");
158   if ((env != NULL) && (strcmp(env, "1") == 0))
159     simd_features |= JSIMD_FASTLD3;
160   if ((env != NULL) && (strcmp(env, "0") == 0))
161     simd_features &= ~JSIMD_FASTLD3;
162   env = getenv("JSIMD_FASTST3");
163   if ((env != NULL) && (strcmp(env, "1") == 0))
164     simd_features |= JSIMD_FASTST3;
165   if ((env != NULL) && (strcmp(env, "0") == 0))
166     simd_features &= ~JSIMD_FASTST3;
167 #endif
168 }
169
170 GLOBAL(int)
171 jsimd_can_rgb_ycc(void)
172 {
173   init_simd();
174
175   /* The code is optimised for these values only */
176   if (BITS_IN_JSAMPLE != 8)
177     return 0;
178   if (sizeof(JDIMENSION) != 4)
179     return 0;
180   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
181     return 0;
182
183   if (simd_support & JSIMD_NEON)
184     return 1;
185
186   return 0;
187 }
188
189 GLOBAL(int)
190 jsimd_can_rgb_gray(void)
191 {
192   return 0;
193 }
194
195 GLOBAL(int)
196 jsimd_can_ycc_rgb(void)
197 {
198   init_simd();
199
200   /* The code is optimised for these values only */
201   if (BITS_IN_JSAMPLE != 8)
202     return 0;
203   if (sizeof(JDIMENSION) != 4)
204     return 0;
205   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
206     return 0;
207
208   if (simd_support & JSIMD_NEON)
209     return 1;
210
211   return 0;
212 }
213
214 GLOBAL(int)
215 jsimd_can_ycc_rgb565(void)
216 {
217   init_simd();
218
219   /* The code is optimised for these values only */
220   if (BITS_IN_JSAMPLE != 8)
221     return 0;
222   if (sizeof(JDIMENSION) != 4)
223     return 0;
224
225   if (simd_support & JSIMD_NEON)
226     return 1;
227
228   return 0;
229 }
230
231 GLOBAL(void)
232 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
233                       JSAMPIMAGE output_buf, JDIMENSION output_row,
234                       int num_rows)
235 {
236   void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
237
238   switch (cinfo->in_color_space) {
239   case JCS_EXT_RGB:
240     if (simd_features & JSIMD_FASTLD3)
241       neonfct = jsimd_extrgb_ycc_convert_neon;
242     else
243       neonfct = jsimd_extrgb_ycc_convert_neon_slowld3;
244     break;
245   case JCS_EXT_RGBX:
246   case JCS_EXT_RGBA:
247     neonfct = jsimd_extrgbx_ycc_convert_neon;
248     break;
249   case JCS_EXT_BGR:
250     if (simd_features & JSIMD_FASTLD3)
251       neonfct = jsimd_extbgr_ycc_convert_neon;
252     else
253       neonfct = jsimd_extbgr_ycc_convert_neon_slowld3;
254     break;
255   case JCS_EXT_BGRX:
256   case JCS_EXT_BGRA:
257     neonfct = jsimd_extbgrx_ycc_convert_neon;
258     break;
259   case JCS_EXT_XBGR:
260   case JCS_EXT_ABGR:
261     neonfct = jsimd_extxbgr_ycc_convert_neon;
262     break;
263   case JCS_EXT_XRGB:
264   case JCS_EXT_ARGB:
265     neonfct = jsimd_extxrgb_ycc_convert_neon;
266     break;
267   default:
268     if (simd_features & JSIMD_FASTLD3)
269       neonfct = jsimd_extrgb_ycc_convert_neon;
270     else
271       neonfct = jsimd_extrgb_ycc_convert_neon_slowld3;
272     break;
273   }
274
275   neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
276 }
277
278 GLOBAL(void)
279 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
280                        JSAMPIMAGE output_buf, JDIMENSION output_row,
281                        int num_rows)
282 {
283 }
284
285 GLOBAL(void)
286 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
287                       JDIMENSION input_row, JSAMPARRAY output_buf,
288                       int num_rows)
289 {
290   void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
291
292   switch (cinfo->out_color_space) {
293   case JCS_EXT_RGB:
294     if (simd_features & JSIMD_FASTST3)
295       neonfct = jsimd_ycc_extrgb_convert_neon;
296     else
297       neonfct = jsimd_ycc_extrgb_convert_neon_slowst3;
298     break;
299   case JCS_EXT_RGBX:
300   case JCS_EXT_RGBA:
301     neonfct = jsimd_ycc_extrgbx_convert_neon;
302     break;
303   case JCS_EXT_BGR:
304     if (simd_features & JSIMD_FASTST3)
305       neonfct = jsimd_ycc_extbgr_convert_neon;
306     else
307       neonfct = jsimd_ycc_extbgr_convert_neon_slowst3;
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     if (simd_features & JSIMD_FASTST3)
323       neonfct = jsimd_ycc_extrgb_convert_neon;
324     else
325       neonfct = jsimd_ycc_extrgb_convert_neon_slowst3;
326     break;
327   }
328
329   neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
330 }
331
332 GLOBAL(void)
333 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
334                          JDIMENSION input_row, JSAMPARRAY output_buf,
335                          int num_rows)
336 {
337   jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
338                                 output_buf, num_rows);
339 }
340
341 GLOBAL(int)
342 jsimd_can_h2v2_downsample(void)
343 {
344   init_simd();
345
346   /* The code is optimised for these values only */
347   if (BITS_IN_JSAMPLE != 8)
348     return 0;
349   if (DCTSIZE != 8)
350     return 0;
351   if (sizeof(JDIMENSION) != 4)
352     return 0;
353
354   if (simd_support & JSIMD_NEON)
355     return 1;
356
357   return 0;
358 }
359
360 GLOBAL(int)
361 jsimd_can_h2v1_downsample(void)
362 {
363   init_simd();
364
365   /* The code is optimised for these values only */
366   if (BITS_IN_JSAMPLE != 8)
367     return 0;
368   if (DCTSIZE != 8)
369     return 0;
370   if (sizeof(JDIMENSION) != 4)
371     return 0;
372
373   if (simd_support & JSIMD_NEON)
374     return 1;
375
376   return 0;
377 }
378
379 GLOBAL(void)
380 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
381                       JSAMPARRAY input_data, JSAMPARRAY output_data)
382 {
383   jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
384                              compptr->v_samp_factor, compptr->width_in_blocks,
385                              input_data, output_data);
386 }
387
388 GLOBAL(void)
389 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
390                       JSAMPARRAY input_data, JSAMPARRAY output_data)
391 {
392   jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
393                              compptr->v_samp_factor, compptr->width_in_blocks,
394                              input_data, output_data);
395 }
396
397 GLOBAL(int)
398 jsimd_can_h2v2_upsample(void)
399 {
400   return 0;
401 }
402
403 GLOBAL(int)
404 jsimd_can_h2v1_upsample(void)
405 {
406   return 0;
407 }
408
409 GLOBAL(void)
410 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
411                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
412 {
413 }
414
415 GLOBAL(void)
416 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
417                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
418 {
419 }
420
421 GLOBAL(int)
422 jsimd_can_h2v2_fancy_upsample(void)
423 {
424   return 0;
425 }
426
427 GLOBAL(int)
428 jsimd_can_h2v1_fancy_upsample(void)
429 {
430   return 0;
431 }
432
433 GLOBAL(void)
434 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
435                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
436 {
437 }
438
439 GLOBAL(void)
440 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
441                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
442 {
443 }
444
445 GLOBAL(int)
446 jsimd_can_h2v2_merged_upsample(void)
447 {
448   return 0;
449 }
450
451 GLOBAL(int)
452 jsimd_can_h2v1_merged_upsample(void)
453 {
454   return 0;
455 }
456
457 GLOBAL(void)
458 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
459                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
460 {
461 }
462
463 GLOBAL(void)
464 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
465                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
466 {
467 }
468
469 GLOBAL(int)
470 jsimd_can_convsamp(void)
471 {
472   init_simd();
473
474   /* The code is optimised for these values only */
475   if (DCTSIZE != 8)
476     return 0;
477   if (BITS_IN_JSAMPLE != 8)
478     return 0;
479   if (sizeof(JDIMENSION) != 4)
480     return 0;
481   if (sizeof(DCTELEM) != 2)
482     return 0;
483
484   if (simd_support & JSIMD_NEON)
485     return 1;
486
487   return 0;
488 }
489
490 GLOBAL(int)
491 jsimd_can_convsamp_float(void)
492 {
493   return 0;
494 }
495
496 GLOBAL(void)
497 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
498                DCTELEM *workspace)
499 {
500   jsimd_convsamp_neon(sample_data, start_col, workspace);
501 }
502
503 GLOBAL(void)
504 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
505                      FAST_FLOAT *workspace)
506 {
507 }
508
509 GLOBAL(int)
510 jsimd_can_fdct_islow(void)
511 {
512   init_simd();
513
514   /* The code is optimised for these values only */
515   if (DCTSIZE != 8)
516     return 0;
517   if (sizeof(DCTELEM) != 2)
518     return 0;
519
520   if (simd_support & JSIMD_NEON)
521     return 1;
522
523   return 0;
524 }
525
526 GLOBAL(int)
527 jsimd_can_fdct_ifast(void)
528 {
529   init_simd();
530
531   /* The code is optimised for these values only */
532   if (DCTSIZE != 8)
533     return 0;
534   if (sizeof(DCTELEM) != 2)
535     return 0;
536
537   if (simd_support & JSIMD_NEON)
538     return 1;
539
540   return 0;
541 }
542
543 GLOBAL(int)
544 jsimd_can_fdct_float(void)
545 {
546   return 0;
547 }
548
549 GLOBAL(void)
550 jsimd_fdct_islow(DCTELEM *data)
551 {
552   jsimd_fdct_islow_neon(data);
553 }
554
555 GLOBAL(void)
556 jsimd_fdct_ifast(DCTELEM *data)
557 {
558   jsimd_fdct_ifast_neon(data);
559 }
560
561 GLOBAL(void)
562 jsimd_fdct_float(FAST_FLOAT *data)
563 {
564 }
565
566 GLOBAL(int)
567 jsimd_can_quantize(void)
568 {
569   init_simd();
570
571   /* The code is optimised for these values only */
572   if (DCTSIZE != 8)
573     return 0;
574   if (sizeof(JCOEF) != 2)
575     return 0;
576   if (sizeof(DCTELEM) != 2)
577     return 0;
578
579   if (simd_support & JSIMD_NEON)
580     return 1;
581
582   return 0;
583 }
584
585 GLOBAL(int)
586 jsimd_can_quantize_float(void)
587 {
588   return 0;
589 }
590
591 GLOBAL(void)
592 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
593 {
594   jsimd_quantize_neon(coef_block, divisors, workspace);
595 }
596
597 GLOBAL(void)
598 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
599                      FAST_FLOAT *workspace)
600 {
601 }
602
603 GLOBAL(int)
604 jsimd_can_idct_2x2(void)
605 {
606   init_simd();
607
608   /* The code is optimised for these values only */
609   if (DCTSIZE != 8)
610     return 0;
611   if (sizeof(JCOEF) != 2)
612     return 0;
613   if (BITS_IN_JSAMPLE != 8)
614     return 0;
615   if (sizeof(JDIMENSION) != 4)
616     return 0;
617   if (sizeof(ISLOW_MULT_TYPE) != 2)
618     return 0;
619
620   if (simd_support & JSIMD_NEON)
621     return 1;
622
623   return 0;
624 }
625
626 GLOBAL(int)
627 jsimd_can_idct_4x4(void)
628 {
629   init_simd();
630
631   /* The code is optimised for these values only */
632   if (DCTSIZE != 8)
633     return 0;
634   if (sizeof(JCOEF) != 2)
635     return 0;
636   if (BITS_IN_JSAMPLE != 8)
637     return 0;
638   if (sizeof(JDIMENSION) != 4)
639     return 0;
640   if (sizeof(ISLOW_MULT_TYPE) != 2)
641     return 0;
642
643   if (simd_support & JSIMD_NEON)
644     return 1;
645
646   return 0;
647 }
648
649 GLOBAL(void)
650 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
651                JCOEFPTR coef_block, JSAMPARRAY output_buf,
652                JDIMENSION output_col)
653 {
654   jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
655 }
656
657 GLOBAL(void)
658 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
659                JCOEFPTR coef_block, JSAMPARRAY output_buf,
660                JDIMENSION output_col)
661 {
662   jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
663 }
664
665 GLOBAL(int)
666 jsimd_can_idct_islow(void)
667 {
668   init_simd();
669
670   /* The code is optimised for these values only */
671   if (DCTSIZE != 8)
672     return 0;
673   if (sizeof(JCOEF) != 2)
674     return 0;
675   if (BITS_IN_JSAMPLE != 8)
676     return 0;
677   if (sizeof(JDIMENSION) != 4)
678     return 0;
679   if (sizeof(ISLOW_MULT_TYPE) != 2)
680     return 0;
681
682   if (simd_support & JSIMD_NEON)
683     return 1;
684
685   return 0;
686 }
687
688 GLOBAL(int)
689 jsimd_can_idct_ifast(void)
690 {
691   init_simd();
692
693   /* The code is optimised for these values only */
694   if (DCTSIZE != 8)
695     return 0;
696   if (sizeof(JCOEF) != 2)
697     return 0;
698   if (BITS_IN_JSAMPLE != 8)
699     return 0;
700   if (sizeof(JDIMENSION) != 4)
701     return 0;
702   if (sizeof(IFAST_MULT_TYPE) != 2)
703     return 0;
704   if (IFAST_SCALE_BITS != 2)
705     return 0;
706
707   if (simd_support & JSIMD_NEON)
708     return 1;
709
710   return 0;
711 }
712
713 GLOBAL(int)
714 jsimd_can_idct_float(void)
715 {
716   return 0;
717 }
718
719 GLOBAL(void)
720 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
721                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
722                  JDIMENSION output_col)
723 {
724   jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
725                         output_col);
726 }
727
728 GLOBAL(void)
729 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
730                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
731                  JDIMENSION output_col)
732 {
733   jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
734                         output_col);
735 }
736
737 GLOBAL(void)
738 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
739                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
740                  JDIMENSION output_col)
741 {
742 }
743
744 GLOBAL(int)
745 jsimd_can_huff_encode_one_block(void)
746 {
747   init_simd();
748
749   if (DCTSIZE != 8)
750     return 0;
751   if (sizeof(JCOEF) != 2)
752     return 0;
753
754   if (simd_support & JSIMD_NEON && simd_huffman)
755     return 1;
756
757   return 0;
758 }
759
760 GLOBAL(JOCTET *)
761 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
762                             int last_dc_val, c_derived_tbl *dctbl,
763                             c_derived_tbl *actbl)
764 {
765   if (simd_features & JSIMD_FASTTBL)
766     return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
767                                             dctbl, actbl);
768   else
769     return jsimd_huff_encode_one_block_neon_slowtbl(state, buffer, block,
770                                                     last_dc_val, dctbl, actbl);
771 }
772
773 GLOBAL(int)
774 jsimd_can_encode_mcu_AC_first_prepare(void)
775 {
776   return 0;
777 }
778
779 GLOBAL(void)
780 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
781                                   const int *jpeg_natural_order_start, int Sl,
782                                   int Al, JCOEF *values, size_t *zerobits)
783 {
784 }
785
786 GLOBAL(int)
787 jsimd_can_encode_mcu_AC_refine_prepare(void)
788 {
789   return 0;
790 }
791
792 GLOBAL(int)
793 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
794                                    const int *jpeg_natural_order_start, int Sl,
795                                    int Al, JCOEF *absvalues, size_t *bits)
796 {
797   return 0;
798 }