• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, D. R. Commander.
7  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
8  * Copyright (C) 2019, Google LLC.
9  *
10  * Based on the x86 SIMD extension for IJG JPEG library,
11  * Copyright (C) 1999-2006, MIYASAKA Masaru.
12  * For conditions of distribution and use, see copyright notice in jsimdext.inc
13  *
14  * This file contains the interface between the "normal" portions
15  * of the library and the SIMD implementations when running on a
16  * 32-bit ARM architecture.
17  */
18 
19 #define JPEG_INTERNALS
20 #include "../../jinclude.h"
21 #include "../../jpeglib.h"
22 #include "../../jsimd.h"
23 #include "../../jdct.h"
24 #include "../../jsimddct.h"
25 #include "../jsimd.h"
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 
31 static unsigned int simd_support = ~0;
32 static unsigned int simd_huffman = 1;
33 
34 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
35 
36 #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT  (1024 * 1024)
37 
38 LOCAL(int)
check_feature(char * buffer,char * feature)39 check_feature(char *buffer, char *feature)
40 {
41   char *p;
42 
43   if (*feature == 0)
44     return 0;
45   if (strncmp(buffer, "Features", 8) != 0)
46     return 0;
47   buffer += 8;
48   while (isspace(*buffer))
49     buffer++;
50 
51   /* Check if 'feature' is present in the buffer as a separate word */
52   while ((p = strstr(buffer, feature))) {
53     if (p > buffer && !isspace(*(p - 1))) {
54       buffer++;
55       continue;
56     }
57     p += strlen(feature);
58     if (*p != 0 && !isspace(*p)) {
59       buffer++;
60       continue;
61     }
62     return 1;
63   }
64   return 0;
65 }
66 
67 LOCAL(int)
parse_proc_cpuinfo(int bufsize)68 parse_proc_cpuinfo(int bufsize)
69 {
70   char *buffer = (char *)malloc(bufsize);
71   FILE *fd;
72 
73   simd_support = 0;
74 
75   if (!buffer)
76     return 0;
77 
78   fd = fopen("/proc/cpuinfo", "r");
79   if (fd) {
80     while (fgets(buffer, bufsize, fd)) {
81       if (!strchr(buffer, '\n') && !feof(fd)) {
82         /* "impossible" happened - insufficient size of the buffer! */
83         fclose(fd);
84         free(buffer);
85         return 0;
86       }
87       if (check_feature(buffer, "neon"))
88         simd_support |= JSIMD_NEON;
89     }
90     fclose(fd);
91   }
92   free(buffer);
93   return 1;
94 }
95 
96 #endif
97 
98 /*
99  * Check what SIMD accelerations are supported.
100  *
101  * FIXME: This code is racy under a multi-threaded environment.
102  */
103 LOCAL(void)
init_simd(void)104 init_simd(void)
105 {
106 #ifndef NO_GETENV
107   char *env = NULL;
108 #endif
109 #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
110   int bufsize = 1024; /* an initial guess for the line buffer size limit */
111 #endif
112 
113   if (simd_support != ~0U)
114     return;
115 
116   simd_support = 0;
117 
118 #if defined(__ARM_NEON__)
119   simd_support |= JSIMD_NEON;
120 #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
121   /* We still have a chance to use NEON regardless of globally used
122    * -mcpu/-mfpu options passed to gcc by performing runtime detection via
123    * /proc/cpuinfo parsing on linux/android */
124   while (!parse_proc_cpuinfo(bufsize)) {
125     bufsize *= 2;
126     if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
127       break;
128   }
129 #endif
130 
131 #ifndef NO_GETENV
132   /* Force different settings through environment variables */
133   env = getenv("JSIMD_FORCENEON");
134   if ((env != NULL) && (strcmp(env, "1") == 0))
135     simd_support = JSIMD_NEON;
136   env = getenv("JSIMD_FORCENONE");
137   if ((env != NULL) && (strcmp(env, "1") == 0))
138     simd_support = 0;
139   env = getenv("JSIMD_NOHUFFENC");
140   if ((env != NULL) && (strcmp(env, "1") == 0))
141     simd_huffman = 0;
142 #endif
143 }
144 
145 GLOBAL(int)
jsimd_can_rgb_ycc(void)146 jsimd_can_rgb_ycc(void)
147 {
148   init_simd();
149 
150   /* The code is optimised for these values only */
151   if (BITS_IN_JSAMPLE != 8)
152     return 0;
153   if (sizeof(JDIMENSION) != 4)
154     return 0;
155   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
156     return 0;
157 
158   if (simd_support & JSIMD_NEON)
159     return 1;
160 
161   return 0;
162 }
163 
164 GLOBAL(int)
jsimd_can_rgb_gray(void)165 jsimd_can_rgb_gray(void)
166 {
167   return 0;
168 }
169 
170 GLOBAL(int)
jsimd_can_ycc_rgb(void)171 jsimd_can_ycc_rgb(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)
jsimd_can_ycc_rgb565(void)190 jsimd_can_ycc_rgb565(void)
191 {
192   init_simd();
193 
194   /* The code is optimised for these values only */
195   if (BITS_IN_JSAMPLE != 8)
196     return 0;
197   if (sizeof(JDIMENSION) != 4)
198     return 0;
199 
200   if (simd_support & JSIMD_NEON)
201     return 1;
202 
203   return 0;
204 }
205 
206 GLOBAL(void)
jsimd_rgb_ycc_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)207 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
208                       JSAMPIMAGE output_buf, JDIMENSION output_row,
209                       int num_rows)
210 {
211   void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
212 
213   switch (cinfo->in_color_space) {
214   case JCS_EXT_RGB:
215     neonfct = jsimd_extrgb_ycc_convert_neon;
216     break;
217   case JCS_EXT_RGBX:
218   case JCS_EXT_RGBA:
219     neonfct = jsimd_extrgbx_ycc_convert_neon;
220     break;
221   case JCS_EXT_BGR:
222     neonfct = jsimd_extbgr_ycc_convert_neon;
223     break;
224   case JCS_EXT_BGRX:
225   case JCS_EXT_BGRA:
226     neonfct = jsimd_extbgrx_ycc_convert_neon;
227     break;
228   case JCS_EXT_XBGR:
229   case JCS_EXT_ABGR:
230     neonfct = jsimd_extxbgr_ycc_convert_neon;
231     break;
232   case JCS_EXT_XRGB:
233   case JCS_EXT_ARGB:
234     neonfct = jsimd_extxrgb_ycc_convert_neon;
235     break;
236   default:
237     neonfct = jsimd_extrgb_ycc_convert_neon;
238     break;
239   }
240 
241   neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
242 }
243 
244 GLOBAL(void)
jsimd_rgb_gray_convert(j_compress_ptr cinfo,JSAMPARRAY input_buf,JSAMPIMAGE output_buf,JDIMENSION output_row,int num_rows)245 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
246                        JSAMPIMAGE output_buf, JDIMENSION output_row,
247                        int num_rows)
248 {
249 }
250 
251 GLOBAL(void)
jsimd_ycc_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)252 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
253                       JDIMENSION input_row, JSAMPARRAY output_buf,
254                       int num_rows)
255 {
256   void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
257 
258   switch (cinfo->out_color_space) {
259   case JCS_EXT_RGB:
260     neonfct = jsimd_ycc_extrgb_convert_neon;
261     break;
262   case JCS_EXT_RGBX:
263   case JCS_EXT_RGBA:
264     neonfct = jsimd_ycc_extrgbx_convert_neon;
265     break;
266   case JCS_EXT_BGR:
267     neonfct = jsimd_ycc_extbgr_convert_neon;
268     break;
269   case JCS_EXT_BGRX:
270   case JCS_EXT_BGRA:
271     neonfct = jsimd_ycc_extbgrx_convert_neon;
272     break;
273   case JCS_EXT_XBGR:
274   case JCS_EXT_ABGR:
275     neonfct = jsimd_ycc_extxbgr_convert_neon;
276     break;
277   case JCS_EXT_XRGB:
278   case JCS_EXT_ARGB:
279     neonfct = jsimd_ycc_extxrgb_convert_neon;
280     break;
281   default:
282     neonfct = jsimd_ycc_extrgb_convert_neon;
283     break;
284   }
285 
286   neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
287 }
288 
289 GLOBAL(void)
jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)290 jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
291                          JDIMENSION input_row, JSAMPARRAY output_buf,
292                          int num_rows)
293 {
294   jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
295                                 output_buf, num_rows);
296 }
297 
298 GLOBAL(int)
jsimd_can_h2v2_downsample(void)299 jsimd_can_h2v2_downsample(void)
300 {
301   return 0;
302 }
303 
304 GLOBAL(int)
jsimd_can_h2v1_downsample(void)305 jsimd_can_h2v1_downsample(void)
306 {
307   return 0;
308 }
309 
310 GLOBAL(void)
jsimd_h2v2_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)311 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
312                       JSAMPARRAY input_data, JSAMPARRAY output_data)
313 {
314 }
315 
316 GLOBAL(void)
jsimd_h2v1_downsample(j_compress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY output_data)317 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
318                       JSAMPARRAY input_data, JSAMPARRAY output_data)
319 {
320 }
321 
322 GLOBAL(int)
jsimd_can_h2v2_upsample(void)323 jsimd_can_h2v2_upsample(void)
324 {
325   return 0;
326 }
327 
328 GLOBAL(int)
jsimd_can_h2v1_upsample(void)329 jsimd_can_h2v1_upsample(void)
330 {
331   return 0;
332 }
333 
334 GLOBAL(void)
jsimd_h2v2_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)335 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
336                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
337 {
338 }
339 
340 GLOBAL(void)
jsimd_h2v1_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)341 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
342                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
343 {
344 }
345 
346 GLOBAL(int)
jsimd_can_h2v2_fancy_upsample(void)347 jsimd_can_h2v2_fancy_upsample(void)
348 {
349   return 0;
350 }
351 
352 GLOBAL(int)
jsimd_can_h2v1_fancy_upsample(void)353 jsimd_can_h2v1_fancy_upsample(void)
354 {
355   init_simd();
356 
357   /* The code is optimised for these values only */
358   if (BITS_IN_JSAMPLE != 8)
359     return 0;
360   if (sizeof(JDIMENSION) != 4)
361     return 0;
362 
363   if (simd_support & JSIMD_NEON)
364     return 1;
365 
366   return 0;
367 }
368 
369 GLOBAL(void)
jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)370 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
371                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
372 {
373 }
374 
375 GLOBAL(void)
jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo,jpeg_component_info * compptr,JSAMPARRAY input_data,JSAMPARRAY * output_data_ptr)376 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
377                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
378 {
379   jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
380                                  compptr->downsampled_width, input_data,
381                                  output_data_ptr);
382 }
383 
384 GLOBAL(int)
jsimd_can_h2v2_merged_upsample(void)385 jsimd_can_h2v2_merged_upsample(void)
386 {
387   return 0;
388 }
389 
390 GLOBAL(int)
jsimd_can_h2v1_merged_upsample(void)391 jsimd_can_h2v1_merged_upsample(void)
392 {
393   return 0;
394 }
395 
396 GLOBAL(void)
jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)397 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
398                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
399 {
400 }
401 
402 GLOBAL(void)
jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION in_row_group_ctr,JSAMPARRAY output_buf)403 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
404                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
405 {
406 }
407 
408 GLOBAL(int)
jsimd_can_convsamp(void)409 jsimd_can_convsamp(void)
410 {
411   init_simd();
412 
413   /* The code is optimised for these values only */
414   if (DCTSIZE != 8)
415     return 0;
416   if (BITS_IN_JSAMPLE != 8)
417     return 0;
418   if (sizeof(JDIMENSION) != 4)
419     return 0;
420   if (sizeof(DCTELEM) != 2)
421     return 0;
422 
423   if (simd_support & JSIMD_NEON)
424     return 1;
425 
426   return 0;
427 }
428 
429 GLOBAL(int)
jsimd_can_convsamp_float(void)430 jsimd_can_convsamp_float(void)
431 {
432   return 0;
433 }
434 
435 GLOBAL(void)
jsimd_convsamp(JSAMPARRAY sample_data,JDIMENSION start_col,DCTELEM * workspace)436 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
437                DCTELEM *workspace)
438 {
439   jsimd_convsamp_neon(sample_data, start_col, workspace);
440 }
441 
442 GLOBAL(void)
jsimd_convsamp_float(JSAMPARRAY sample_data,JDIMENSION start_col,FAST_FLOAT * workspace)443 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
444                      FAST_FLOAT *workspace)
445 {
446 }
447 
448 GLOBAL(int)
jsimd_can_fdct_islow(void)449 jsimd_can_fdct_islow(void)
450 {
451   return 0;
452 }
453 
454 GLOBAL(int)
jsimd_can_fdct_ifast(void)455 jsimd_can_fdct_ifast(void)
456 {
457   init_simd();
458 
459   /* The code is optimised for these values only */
460   if (DCTSIZE != 8)
461     return 0;
462   if (sizeof(DCTELEM) != 2)
463     return 0;
464 
465   if (simd_support & JSIMD_NEON)
466     return 1;
467 
468   return 0;
469 }
470 
471 GLOBAL(int)
jsimd_can_fdct_float(void)472 jsimd_can_fdct_float(void)
473 {
474   return 0;
475 }
476 
477 GLOBAL(void)
jsimd_fdct_islow(DCTELEM * data)478 jsimd_fdct_islow(DCTELEM *data)
479 {
480 }
481 
482 GLOBAL(void)
jsimd_fdct_ifast(DCTELEM * data)483 jsimd_fdct_ifast(DCTELEM *data)
484 {
485   jsimd_fdct_ifast_neon(data);
486 }
487 
488 GLOBAL(void)
jsimd_fdct_float(FAST_FLOAT * data)489 jsimd_fdct_float(FAST_FLOAT *data)
490 {
491 }
492 
493 GLOBAL(int)
jsimd_can_quantize(void)494 jsimd_can_quantize(void)
495 {
496   init_simd();
497 
498   /* The code is optimised for these values only */
499   if (DCTSIZE != 8)
500     return 0;
501   if (sizeof(JCOEF) != 2)
502     return 0;
503   if (sizeof(DCTELEM) != 2)
504     return 0;
505 
506   if (simd_support & JSIMD_NEON)
507     return 1;
508 
509   return 0;
510 }
511 
512 GLOBAL(int)
jsimd_can_quantize_float(void)513 jsimd_can_quantize_float(void)
514 {
515   return 0;
516 }
517 
518 GLOBAL(void)
jsimd_quantize(JCOEFPTR coef_block,DCTELEM * divisors,DCTELEM * workspace)519 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
520 {
521   jsimd_quantize_neon(coef_block, divisors, workspace);
522 }
523 
524 GLOBAL(void)
jsimd_quantize_float(JCOEFPTR coef_block,FAST_FLOAT * divisors,FAST_FLOAT * workspace)525 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
526                      FAST_FLOAT *workspace)
527 {
528 }
529 
530 GLOBAL(int)
jsimd_can_idct_2x2(void)531 jsimd_can_idct_2x2(void)
532 {
533   init_simd();
534 
535   /* The code is optimised for these values only */
536   if (DCTSIZE != 8)
537     return 0;
538   if (sizeof(JCOEF) != 2)
539     return 0;
540   if (BITS_IN_JSAMPLE != 8)
541     return 0;
542   if (sizeof(JDIMENSION) != 4)
543     return 0;
544   if (sizeof(ISLOW_MULT_TYPE) != 2)
545     return 0;
546 
547   if (simd_support & JSIMD_NEON)
548     return 1;
549 
550   return 0;
551 }
552 
553 GLOBAL(int)
jsimd_can_idct_4x4(void)554 jsimd_can_idct_4x4(void)
555 {
556   init_simd();
557 
558   /* The code is optimised for these values only */
559   if (DCTSIZE != 8)
560     return 0;
561   if (sizeof(JCOEF) != 2)
562     return 0;
563   if (BITS_IN_JSAMPLE != 8)
564     return 0;
565   if (sizeof(JDIMENSION) != 4)
566     return 0;
567   if (sizeof(ISLOW_MULT_TYPE) != 2)
568     return 0;
569 
570   if (simd_support & JSIMD_NEON)
571     return 1;
572 
573   return 0;
574 }
575 
576 GLOBAL(void)
jsimd_idct_2x2(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)577 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
578                JCOEFPTR coef_block, JSAMPARRAY output_buf,
579                JDIMENSION output_col)
580 {
581   jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
582 }
583 
584 GLOBAL(void)
jsimd_idct_4x4(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)585 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
586                JCOEFPTR coef_block, JSAMPARRAY output_buf,
587                JDIMENSION output_col)
588 {
589   jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
590 }
591 
592 GLOBAL(int)
jsimd_can_idct_islow(void)593 jsimd_can_idct_islow(void)
594 {
595   init_simd();
596 
597   /* The code is optimised for these values only */
598   if (DCTSIZE != 8)
599     return 0;
600   if (sizeof(JCOEF) != 2)
601     return 0;
602   if (BITS_IN_JSAMPLE != 8)
603     return 0;
604   if (sizeof(JDIMENSION) != 4)
605     return 0;
606   if (sizeof(ISLOW_MULT_TYPE) != 2)
607     return 0;
608 
609   if (simd_support & JSIMD_NEON)
610     return 1;
611 
612   return 0;
613 }
614 
615 GLOBAL(int)
jsimd_can_idct_ifast(void)616 jsimd_can_idct_ifast(void)
617 {
618   init_simd();
619 
620   /* The code is optimised for these values only */
621   if (DCTSIZE != 8)
622     return 0;
623   if (sizeof(JCOEF) != 2)
624     return 0;
625   if (BITS_IN_JSAMPLE != 8)
626     return 0;
627   if (sizeof(JDIMENSION) != 4)
628     return 0;
629   if (sizeof(IFAST_MULT_TYPE) != 2)
630     return 0;
631   if (IFAST_SCALE_BITS != 2)
632     return 0;
633 
634   if (simd_support & JSIMD_NEON)
635     return 1;
636 
637   return 0;
638 }
639 
640 GLOBAL(int)
jsimd_can_idct_float(void)641 jsimd_can_idct_float(void)
642 {
643   return 0;
644 }
645 
646 GLOBAL(void)
jsimd_idct_islow(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)647 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
648                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
649                  JDIMENSION output_col)
650 {
651   jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
652                         output_col);
653 }
654 
655 GLOBAL(void)
jsimd_idct_ifast(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)656 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
657                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
658                  JDIMENSION output_col)
659 {
660   jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
661                         output_col);
662 }
663 
664 GLOBAL(void)
jsimd_idct_float(j_decompress_ptr cinfo,jpeg_component_info * compptr,JCOEFPTR coef_block,JSAMPARRAY output_buf,JDIMENSION output_col)665 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
666                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
667                  JDIMENSION output_col)
668 {
669 }
670 
671 GLOBAL(int)
jsimd_can_huff_encode_one_block(void)672 jsimd_can_huff_encode_one_block(void)
673 {
674   init_simd();
675 
676   if (DCTSIZE != 8)
677     return 0;
678   if (sizeof(JCOEF) != 2)
679     return 0;
680 
681   if (simd_support & JSIMD_NEON && simd_huffman)
682     return 1;
683 
684   return 0;
685 }
686 
687 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)688 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
689                             int last_dc_val, c_derived_tbl *dctbl,
690                             c_derived_tbl *actbl)
691 {
692   return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
693                                           dctbl, actbl);
694 }
695 
696 GLOBAL(int)
jsimd_can_encode_mcu_AC_first_prepare(void)697 jsimd_can_encode_mcu_AC_first_prepare(void)
698 {
699   return 0;
700 }
701 
702 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)703 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
704                                   const int *jpeg_natural_order_start, int Sl,
705                                   int Al, JCOEF *values, size_t *zerobits)
706 {
707 }
708 
709 GLOBAL(int)
jsimd_can_encode_mcu_AC_refine_prepare(void)710 jsimd_can_encode_mcu_AC_refine_prepare(void)
711 {
712   return 0;
713 }
714 
715 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)716 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
717                                    const int *jpeg_natural_order_start, int Sl,
718                                    int Al, JCOEF *absvalues, size_t *bits)
719 {
720   return 0;
721 }
722