4 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5 * Copyright 2009-2011, 2013-2014 D. R. Commander
7 * Based on the x86 SIMD extension for IJG JPEG library,
8 * Copyright (C) 1999-2006, MIYASAKA Masaru.
9 * For conditions of distribution and use, see copyright notice in jsimdext.inc
11 * This file contains the interface between the "normal" portions
12 * of the library and the SIMD implementations when running on a
13 * 64-bit ARM architecture.
16 #define JPEG_INTERNALS
17 #include "../jinclude.h"
18 #include "../jpeglib.h"
21 #include "../jsimddct.h"
28 static unsigned int simd_support = ~0;
31 * Check what SIMD accelerations are supported.
33 * FIXME: This code is racy under a multi-threaded environment.
37 * ARMv8 architectures support NEON extensions by default.
38 * It is no longer optional as it was with ARMv7.
47 if (simd_support != ~0U)
52 simd_support |= JSIMD_ARM_NEON;
54 /* Force different settings through environment variables */
55 env = getenv("JSIMD_FORCENEON");
56 if ((env != NULL) && (strcmp(env, "1") == 0))
57 simd_support &= JSIMD_ARM_NEON;
58 env = getenv("JSIMD_FORCENONE");
59 if ((env != NULL) && (strcmp(env, "1") == 0))
64 jsimd_can_rgb_ycc (void)
72 jsimd_can_rgb_gray (void)
80 jsimd_can_ycc_rgb (void)
84 /* The code is optimised for these values only */
85 if (BITS_IN_JSAMPLE != 8)
87 if (sizeof(JDIMENSION) != 4)
89 if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
92 if (simd_support & JSIMD_ARM_NEON)
99 jsimd_can_ycc_rgb565 (void)
103 /* The code is optimised for these values only */
104 if (BITS_IN_JSAMPLE != 8)
106 if (sizeof(JDIMENSION) != 4)
109 if (simd_support & JSIMD_ARM_NEON)
116 jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
117 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
118 JDIMENSION output_row, int num_rows)
123 jsimd_rgb_gray_convert (j_compress_ptr cinfo,
124 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
125 JDIMENSION output_row, int num_rows)
130 jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
131 JSAMPIMAGE input_buf, JDIMENSION input_row,
132 JSAMPARRAY output_buf, int num_rows)
134 void (*neonfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
136 switch(cinfo->out_color_space) {
138 neonfct=jsimd_ycc_extrgb_convert_neon;
142 neonfct=jsimd_ycc_extrgbx_convert_neon;
145 neonfct=jsimd_ycc_extbgr_convert_neon;
149 neonfct=jsimd_ycc_extbgrx_convert_neon;
153 neonfct=jsimd_ycc_extxbgr_convert_neon;
157 neonfct=jsimd_ycc_extxrgb_convert_neon;
160 neonfct=jsimd_ycc_extrgb_convert_neon;
164 if (simd_support & JSIMD_ARM_NEON)
165 neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
169 jsimd_ycc_rgb565_convert (j_decompress_ptr cinfo,
170 JSAMPIMAGE input_buf, JDIMENSION input_row,
171 JSAMPARRAY output_buf, int num_rows)
173 if (simd_support & JSIMD_ARM_NEON)
174 jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
175 output_buf, num_rows);
179 jsimd_can_h2v2_downsample (void)
187 jsimd_can_h2v1_downsample (void)
195 jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
196 JSAMPARRAY input_data, JSAMPARRAY output_data)
201 jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
202 JSAMPARRAY input_data, JSAMPARRAY output_data)
207 jsimd_can_h2v2_upsample (void)
215 jsimd_can_h2v1_upsample (void)
223 jsimd_h2v2_upsample (j_decompress_ptr cinfo,
224 jpeg_component_info * compptr,
225 JSAMPARRAY input_data,
226 JSAMPARRAY * output_data_ptr)
231 jsimd_h2v1_upsample (j_decompress_ptr cinfo,
232 jpeg_component_info * compptr,
233 JSAMPARRAY input_data,
234 JSAMPARRAY * output_data_ptr)
239 jsimd_can_h2v2_fancy_upsample (void)
247 jsimd_can_h2v1_fancy_upsample (void)
255 jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
256 jpeg_component_info * compptr,
257 JSAMPARRAY input_data,
258 JSAMPARRAY * output_data_ptr)
263 jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
264 jpeg_component_info * compptr,
265 JSAMPARRAY input_data,
266 JSAMPARRAY * output_data_ptr)
271 jsimd_can_h2v2_merged_upsample (void)
279 jsimd_can_h2v1_merged_upsample (void)
287 jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
288 JSAMPIMAGE input_buf,
289 JDIMENSION in_row_group_ctr,
290 JSAMPARRAY output_buf)
295 jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
296 JSAMPIMAGE input_buf,
297 JDIMENSION in_row_group_ctr,
298 JSAMPARRAY output_buf)
303 jsimd_can_convsamp (void)
311 jsimd_can_convsamp_float (void)
319 jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
325 jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
326 FAST_FLOAT * workspace)
331 jsimd_can_fdct_islow (void)
339 jsimd_can_fdct_ifast (void)
347 jsimd_can_fdct_float (void)
355 jsimd_fdct_islow (DCTELEM * data)
360 jsimd_fdct_ifast (DCTELEM * data)
365 jsimd_fdct_float (FAST_FLOAT * data)
370 jsimd_can_quantize (void)
378 jsimd_can_quantize_float (void)
386 jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
392 jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
393 FAST_FLOAT * workspace)
398 jsimd_can_idct_2x2 (void)
402 /* The code is optimised for these values only */
405 if (sizeof(JCOEF) != 2)
407 if (BITS_IN_JSAMPLE != 8)
409 if (sizeof(JDIMENSION) != 4)
411 if (sizeof(ISLOW_MULT_TYPE) != 2)
414 if (simd_support & JSIMD_ARM_NEON)
421 jsimd_can_idct_4x4 (void)
425 /* The code is optimised for these values only */
428 if (sizeof(JCOEF) != 2)
430 if (BITS_IN_JSAMPLE != 8)
432 if (sizeof(JDIMENSION) != 4)
434 if (sizeof(ISLOW_MULT_TYPE) != 2)
437 if (simd_support & JSIMD_ARM_NEON)
444 jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
445 JCOEFPTR coef_block, JSAMPARRAY output_buf,
446 JDIMENSION output_col)
448 if (simd_support & JSIMD_ARM_NEON)
449 jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf,
454 jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
455 JCOEFPTR coef_block, JSAMPARRAY output_buf,
456 JDIMENSION output_col)
458 if (simd_support & JSIMD_ARM_NEON)
459 jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf,
464 jsimd_can_idct_islow (void)
468 /* The code is optimised for these values only */
471 if (sizeof(JCOEF) != 2)
473 if (BITS_IN_JSAMPLE != 8)
475 if (sizeof(JDIMENSION) != 4)
477 if (sizeof(ISLOW_MULT_TYPE) != 2)
480 if (simd_support & JSIMD_ARM_NEON)
487 jsimd_can_idct_ifast (void)
491 /* The code is optimised for these values only */
494 if (sizeof(JCOEF) != 2)
496 if (BITS_IN_JSAMPLE != 8)
498 if (sizeof(JDIMENSION) != 4)
500 if (sizeof(IFAST_MULT_TYPE) != 2)
502 if (IFAST_SCALE_BITS != 2)
505 if (simd_support & JSIMD_ARM_NEON)
512 jsimd_can_idct_float (void)
520 jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
521 JCOEFPTR coef_block, JSAMPARRAY output_buf,
522 JDIMENSION output_col)
524 if (simd_support & JSIMD_ARM_NEON)
525 jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
530 jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
531 JCOEFPTR coef_block, JSAMPARRAY output_buf,
532 JDIMENSION output_col)
534 if (simd_support & JSIMD_ARM_NEON)
535 jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
540 jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
541 JCOEFPTR coef_block, JSAMPARRAY output_buf,
542 JDIMENSION output_col)