80bc821ff4e7be5b8eb9af9bafae269ea3d47024
[platform/upstream/libjpeg-turbo.git] / simd / i386 / jsimd.c
1 /*
2  * jsimd_i386.c
3  *
4  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5  * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, 2022, D. R. Commander.
6  * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
7  *
8  * Based on the x86 SIMD extension for IJG JPEG library,
9  * Copyright (C) 1999-2006, MIYASAKA Masaru.
10  * For conditions of distribution and use, see copyright notice in jsimdext.inc
11  *
12  * This file contains the interface between the "normal" portions
13  * of the library and the SIMD implementations when running on a
14  * 32-bit x86 architecture.
15  */
16
17 #define JPEG_INTERNALS
18 #include "../../jinclude.h"
19 #include "../../jpeglib.h"
20 #include "../../jsimd.h"
21 #include "../../jdct.h"
22 #include "../../jsimddct.h"
23 #include "../jsimd.h"
24 #include "jconfigint.h"
25
26 /*
27  * In the PIC cases, we have no guarantee that constants will keep
28  * their alignment. This macro allows us to verify it at runtime.
29  */
30 #define IS_ALIGNED(ptr, order)  (((unsigned)ptr & ((1 << order) - 1)) == 0)
31
32 #define IS_ALIGNED_SSE(ptr)  (IS_ALIGNED(ptr, 4)) /* 16 byte alignment */
33 #define IS_ALIGNED_AVX(ptr)  (IS_ALIGNED(ptr, 5)) /* 32 byte alignment */
34
35 static unsigned int simd_support = (unsigned int)(~0);
36 static unsigned int simd_huffman = 1;
37
38 /*
39  * Check what SIMD accelerations are supported.
40  *
41  * FIXME: This code is racy under a multi-threaded environment.
42  */
43 LOCAL(void)
44 init_simd(void)
45 {
46 #ifndef NO_GETENV
47   char env[2] = { 0 };
48 #endif
49
50   if (simd_support != ~0U)
51     return;
52
53   simd_support = jpeg_simd_cpu_support();
54
55 #ifndef NO_GETENV
56   /* Force different settings through environment variables */
57   if (!GETENV_S(env, 2, "JSIMD_FORCEMMX") && !strcmp(env, "1"))
58     simd_support &= JSIMD_MMX;
59   if (!GETENV_S(env, 2, "JSIMD_FORCE3DNOW") && !strcmp(env, "1"))
60     simd_support &= JSIMD_3DNOW | JSIMD_MMX;
61   if (!GETENV_S(env, 2, "JSIMD_FORCESSE") && !strcmp(env, "1"))
62     simd_support &= JSIMD_SSE | JSIMD_MMX;
63   if (!GETENV_S(env, 2, "JSIMD_FORCESSE2") && !strcmp(env, "1"))
64     simd_support &= JSIMD_SSE2;
65   if (!GETENV_S(env, 2, "JSIMD_FORCEAVX2") && !strcmp(env, "1"))
66     simd_support &= JSIMD_AVX2;
67   if (!GETENV_S(env, 2, "JSIMD_FORCENONE") && !strcmp(env, "1"))
68     simd_support = 0;
69   if (!GETENV_S(env, 2, "JSIMD_NOHUFFENC") && !strcmp(env, "1"))
70     simd_huffman = 0;
71 #endif
72 }
73
74 GLOBAL(int)
75 jsimd_can_rgb_ycc(void)
76 {
77   init_simd();
78
79   /* The code is optimised for these values only */
80   if (BITS_IN_JSAMPLE != 8)
81     return 0;
82   if (sizeof(JDIMENSION) != 4)
83     return 0;
84   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
85     return 0;
86
87   if ((simd_support & JSIMD_AVX2) &&
88       IS_ALIGNED_AVX(jconst_rgb_ycc_convert_avx2))
89     return 1;
90   if ((simd_support & JSIMD_SSE2) &&
91       IS_ALIGNED_SSE(jconst_rgb_ycc_convert_sse2))
92     return 1;
93   if (simd_support & JSIMD_MMX)
94     return 1;
95
96   return 0;
97 }
98
99 GLOBAL(int)
100 jsimd_can_rgb_gray(void)
101 {
102   init_simd();
103
104   /* The code is optimised for these values only */
105   if (BITS_IN_JSAMPLE != 8)
106     return 0;
107   if (sizeof(JDIMENSION) != 4)
108     return 0;
109   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
110     return 0;
111
112   if ((simd_support & JSIMD_AVX2) &&
113       IS_ALIGNED_AVX(jconst_rgb_gray_convert_avx2))
114     return 1;
115   if ((simd_support & JSIMD_SSE2) &&
116       IS_ALIGNED_SSE(jconst_rgb_gray_convert_sse2))
117     return 1;
118   if (simd_support & JSIMD_MMX)
119     return 1;
120
121   return 0;
122 }
123
124 GLOBAL(int)
125 jsimd_can_ycc_rgb(void)
126 {
127   init_simd();
128
129   /* The code is optimised for these values only */
130   if (BITS_IN_JSAMPLE != 8)
131     return 0;
132   if (sizeof(JDIMENSION) != 4)
133     return 0;
134   if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
135     return 0;
136
137   if ((simd_support & JSIMD_AVX2) &&
138       IS_ALIGNED_AVX(jconst_ycc_rgb_convert_avx2))
139     return 1;
140   if ((simd_support & JSIMD_SSE2) &&
141       IS_ALIGNED_SSE(jconst_ycc_rgb_convert_sse2))
142     return 1;
143   if (simd_support & JSIMD_MMX)
144     return 1;
145
146   return 0;
147 }
148
149 GLOBAL(int)
150 jsimd_can_ycc_rgb565(void)
151 {
152   return 0;
153 }
154
155 GLOBAL(void)
156 jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
157                       JSAMPIMAGE output_buf, JDIMENSION output_row,
158                       int num_rows)
159 {
160   void (*avx2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
161   void (*sse2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
162   void (*mmxfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
163
164   switch (cinfo->in_color_space) {
165   case JCS_EXT_RGB:
166     avx2fct = jsimd_extrgb_ycc_convert_avx2;
167     sse2fct = jsimd_extrgb_ycc_convert_sse2;
168     mmxfct = jsimd_extrgb_ycc_convert_mmx;
169     break;
170   case JCS_EXT_RGBX:
171   case JCS_EXT_RGBA:
172     avx2fct = jsimd_extrgbx_ycc_convert_avx2;
173     sse2fct = jsimd_extrgbx_ycc_convert_sse2;
174     mmxfct = jsimd_extrgbx_ycc_convert_mmx;
175     break;
176   case JCS_EXT_BGR:
177     avx2fct = jsimd_extbgr_ycc_convert_avx2;
178     sse2fct = jsimd_extbgr_ycc_convert_sse2;
179     mmxfct = jsimd_extbgr_ycc_convert_mmx;
180     break;
181   case JCS_EXT_BGRX:
182   case JCS_EXT_BGRA:
183     avx2fct = jsimd_extbgrx_ycc_convert_avx2;
184     sse2fct = jsimd_extbgrx_ycc_convert_sse2;
185     mmxfct = jsimd_extbgrx_ycc_convert_mmx;
186     break;
187   case JCS_EXT_XBGR:
188   case JCS_EXT_ABGR:
189     avx2fct = jsimd_extxbgr_ycc_convert_avx2;
190     sse2fct = jsimd_extxbgr_ycc_convert_sse2;
191     mmxfct = jsimd_extxbgr_ycc_convert_mmx;
192     break;
193   case JCS_EXT_XRGB:
194   case JCS_EXT_ARGB:
195     avx2fct = jsimd_extxrgb_ycc_convert_avx2;
196     sse2fct = jsimd_extxrgb_ycc_convert_sse2;
197     mmxfct = jsimd_extxrgb_ycc_convert_mmx;
198     break;
199   default:
200     avx2fct = jsimd_rgb_ycc_convert_avx2;
201     sse2fct = jsimd_rgb_ycc_convert_sse2;
202     mmxfct = jsimd_rgb_ycc_convert_mmx;
203     break;
204   }
205
206   if (simd_support & JSIMD_AVX2)
207     avx2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
208   else if (simd_support & JSIMD_SSE2)
209     sse2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
210   else
211     mmxfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
212 }
213
214 GLOBAL(void)
215 jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
216                        JSAMPIMAGE output_buf, JDIMENSION output_row,
217                        int num_rows)
218 {
219   void (*avx2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
220   void (*sse2fct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
221   void (*mmxfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
222
223   switch (cinfo->in_color_space) {
224   case JCS_EXT_RGB:
225     avx2fct = jsimd_extrgb_gray_convert_avx2;
226     sse2fct = jsimd_extrgb_gray_convert_sse2;
227     mmxfct = jsimd_extrgb_gray_convert_mmx;
228     break;
229   case JCS_EXT_RGBX:
230   case JCS_EXT_RGBA:
231     avx2fct = jsimd_extrgbx_gray_convert_avx2;
232     sse2fct = jsimd_extrgbx_gray_convert_sse2;
233     mmxfct = jsimd_extrgbx_gray_convert_mmx;
234     break;
235   case JCS_EXT_BGR:
236     avx2fct = jsimd_extbgr_gray_convert_avx2;
237     sse2fct = jsimd_extbgr_gray_convert_sse2;
238     mmxfct = jsimd_extbgr_gray_convert_mmx;
239     break;
240   case JCS_EXT_BGRX:
241   case JCS_EXT_BGRA:
242     avx2fct = jsimd_extbgrx_gray_convert_avx2;
243     sse2fct = jsimd_extbgrx_gray_convert_sse2;
244     mmxfct = jsimd_extbgrx_gray_convert_mmx;
245     break;
246   case JCS_EXT_XBGR:
247   case JCS_EXT_ABGR:
248     avx2fct = jsimd_extxbgr_gray_convert_avx2;
249     sse2fct = jsimd_extxbgr_gray_convert_sse2;
250     mmxfct = jsimd_extxbgr_gray_convert_mmx;
251     break;
252   case JCS_EXT_XRGB:
253   case JCS_EXT_ARGB:
254     avx2fct = jsimd_extxrgb_gray_convert_avx2;
255     sse2fct = jsimd_extxrgb_gray_convert_sse2;
256     mmxfct = jsimd_extxrgb_gray_convert_mmx;
257     break;
258   default:
259     avx2fct = jsimd_rgb_gray_convert_avx2;
260     sse2fct = jsimd_rgb_gray_convert_sse2;
261     mmxfct = jsimd_rgb_gray_convert_mmx;
262     break;
263   }
264
265   if (simd_support & JSIMD_AVX2)
266     avx2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
267   else if (simd_support & JSIMD_SSE2)
268     sse2fct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
269   else
270     mmxfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
271 }
272
273 GLOBAL(void)
274 jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
275                       JDIMENSION input_row, JSAMPARRAY output_buf,
276                       int num_rows)
277 {
278   void (*avx2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
279   void (*sse2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
280   void (*mmxfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
281
282   switch (cinfo->out_color_space) {
283   case JCS_EXT_RGB:
284     avx2fct = jsimd_ycc_extrgb_convert_avx2;
285     sse2fct = jsimd_ycc_extrgb_convert_sse2;
286     mmxfct = jsimd_ycc_extrgb_convert_mmx;
287     break;
288   case JCS_EXT_RGBX:
289   case JCS_EXT_RGBA:
290     avx2fct = jsimd_ycc_extrgbx_convert_avx2;
291     sse2fct = jsimd_ycc_extrgbx_convert_sse2;
292     mmxfct = jsimd_ycc_extrgbx_convert_mmx;
293     break;
294   case JCS_EXT_BGR:
295     avx2fct = jsimd_ycc_extbgr_convert_avx2;
296     sse2fct = jsimd_ycc_extbgr_convert_sse2;
297     mmxfct = jsimd_ycc_extbgr_convert_mmx;
298     break;
299   case JCS_EXT_BGRX:
300   case JCS_EXT_BGRA:
301     avx2fct = jsimd_ycc_extbgrx_convert_avx2;
302     sse2fct = jsimd_ycc_extbgrx_convert_sse2;
303     mmxfct = jsimd_ycc_extbgrx_convert_mmx;
304     break;
305   case JCS_EXT_XBGR:
306   case JCS_EXT_ABGR:
307     avx2fct = jsimd_ycc_extxbgr_convert_avx2;
308     sse2fct = jsimd_ycc_extxbgr_convert_sse2;
309     mmxfct = jsimd_ycc_extxbgr_convert_mmx;
310     break;
311   case JCS_EXT_XRGB:
312   case JCS_EXT_ARGB:
313     avx2fct = jsimd_ycc_extxrgb_convert_avx2;
314     sse2fct = jsimd_ycc_extxrgb_convert_sse2;
315     mmxfct = jsimd_ycc_extxrgb_convert_mmx;
316     break;
317   default:
318     avx2fct = jsimd_ycc_rgb_convert_avx2;
319     sse2fct = jsimd_ycc_rgb_convert_sse2;
320     mmxfct = jsimd_ycc_rgb_convert_mmx;
321     break;
322   }
323
324   if (simd_support & JSIMD_AVX2)
325     avx2fct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
326   else if (simd_support & JSIMD_SSE2)
327     sse2fct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
328   else
329     mmxfct(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 }
338
339 GLOBAL(int)
340 jsimd_can_h2v2_downsample(void)
341 {
342   init_simd();
343
344   /* The code is optimised for these values only */
345   if (BITS_IN_JSAMPLE != 8)
346     return 0;
347   if (sizeof(JDIMENSION) != 4)
348     return 0;
349
350   if (simd_support & JSIMD_AVX2)
351     return 1;
352   if (simd_support & JSIMD_SSE2)
353     return 1;
354   if (simd_support & JSIMD_MMX)
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 (sizeof(JDIMENSION) != 4)
369     return 0;
370
371   if (simd_support & JSIMD_AVX2)
372     return 1;
373   if (simd_support & JSIMD_SSE2)
374     return 1;
375   if (simd_support & JSIMD_MMX)
376     return 1;
377
378   return 0;
379 }
380
381 GLOBAL(void)
382 jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
383                       JSAMPARRAY input_data, JSAMPARRAY output_data)
384 {
385   if (simd_support & JSIMD_AVX2)
386     jsimd_h2v2_downsample_avx2(cinfo->image_width, cinfo->max_v_samp_factor,
387                                compptr->v_samp_factor,
388                                compptr->width_in_blocks, input_data,
389                                output_data);
390   else if (simd_support & JSIMD_SSE2)
391     jsimd_h2v2_downsample_sse2(cinfo->image_width, cinfo->max_v_samp_factor,
392                                compptr->v_samp_factor,
393                                compptr->width_in_blocks, input_data,
394                                output_data);
395   else
396     jsimd_h2v2_downsample_mmx(cinfo->image_width, cinfo->max_v_samp_factor,
397                               compptr->v_samp_factor, compptr->width_in_blocks,
398                               input_data, output_data);
399 }
400
401 GLOBAL(void)
402 jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
403                       JSAMPARRAY input_data, JSAMPARRAY output_data)
404 {
405   if (simd_support & JSIMD_AVX2)
406     jsimd_h2v1_downsample_avx2(cinfo->image_width, cinfo->max_v_samp_factor,
407                                compptr->v_samp_factor,
408                                compptr->width_in_blocks, input_data,
409                                output_data);
410   else if (simd_support & JSIMD_SSE2)
411     jsimd_h2v1_downsample_sse2(cinfo->image_width, cinfo->max_v_samp_factor,
412                                compptr->v_samp_factor,
413                                compptr->width_in_blocks, input_data,
414                                output_data);
415   else
416     jsimd_h2v1_downsample_mmx(cinfo->image_width, cinfo->max_v_samp_factor,
417                               compptr->v_samp_factor, compptr->width_in_blocks,
418                               input_data, output_data);
419 }
420
421 GLOBAL(int)
422 jsimd_can_h2v2_upsample(void)
423 {
424   init_simd();
425
426   /* The code is optimised for these values only */
427   if (BITS_IN_JSAMPLE != 8)
428     return 0;
429   if (sizeof(JDIMENSION) != 4)
430     return 0;
431
432   if (simd_support & JSIMD_AVX2)
433     return 1;
434   if (simd_support & JSIMD_SSE2)
435     return 1;
436   if (simd_support & JSIMD_MMX)
437     return 1;
438
439   return 0;
440 }
441
442 GLOBAL(int)
443 jsimd_can_h2v1_upsample(void)
444 {
445   init_simd();
446
447   /* The code is optimised for these values only */
448   if (BITS_IN_JSAMPLE != 8)
449     return 0;
450   if (sizeof(JDIMENSION) != 4)
451     return 0;
452
453   if (simd_support & JSIMD_AVX2)
454     return 1;
455   if (simd_support & JSIMD_SSE2)
456     return 1;
457   if (simd_support & JSIMD_MMX)
458     return 1;
459
460   return 0;
461 }
462
463 GLOBAL(void)
464 jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
465                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
466 {
467   if (simd_support & JSIMD_AVX2)
468     jsimd_h2v2_upsample_avx2(cinfo->max_v_samp_factor, cinfo->output_width,
469                              input_data, output_data_ptr);
470   else if (simd_support & JSIMD_SSE2)
471     jsimd_h2v2_upsample_sse2(cinfo->max_v_samp_factor, cinfo->output_width,
472                              input_data, output_data_ptr);
473   else
474     jsimd_h2v2_upsample_mmx(cinfo->max_v_samp_factor, cinfo->output_width,
475                             input_data, output_data_ptr);
476 }
477
478 GLOBAL(void)
479 jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
480                     JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
481 {
482   if (simd_support & JSIMD_AVX2)
483     jsimd_h2v1_upsample_avx2(cinfo->max_v_samp_factor, cinfo->output_width,
484                              input_data, output_data_ptr);
485   else if (simd_support & JSIMD_SSE2)
486     jsimd_h2v1_upsample_sse2(cinfo->max_v_samp_factor, cinfo->output_width,
487                              input_data, output_data_ptr);
488   else
489     jsimd_h2v1_upsample_mmx(cinfo->max_v_samp_factor, cinfo->output_width,
490                             input_data, output_data_ptr);
491 }
492
493 GLOBAL(int)
494 jsimd_can_h2v2_fancy_upsample(void)
495 {
496   init_simd();
497
498   /* The code is optimised for these values only */
499   if (BITS_IN_JSAMPLE != 8)
500     return 0;
501   if (sizeof(JDIMENSION) != 4)
502     return 0;
503
504   if ((simd_support & JSIMD_AVX2) &&
505       IS_ALIGNED_AVX(jconst_fancy_upsample_avx2))
506     return 1;
507   if ((simd_support & JSIMD_SSE2) &&
508       IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
509     return 1;
510   if (simd_support & JSIMD_MMX)
511     return 1;
512
513   return 0;
514 }
515
516 GLOBAL(int)
517 jsimd_can_h2v1_fancy_upsample(void)
518 {
519   init_simd();
520
521   /* The code is optimised for these values only */
522   if (BITS_IN_JSAMPLE != 8)
523     return 0;
524   if (sizeof(JDIMENSION) != 4)
525     return 0;
526
527   if ((simd_support & JSIMD_AVX2) &&
528       IS_ALIGNED_AVX(jconst_fancy_upsample_avx2))
529     return 1;
530   if ((simd_support & JSIMD_SSE2) &&
531       IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
532     return 1;
533   if (simd_support & JSIMD_MMX)
534     return 1;
535
536   return 0;
537 }
538
539 GLOBAL(void)
540 jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
541                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
542 {
543   if (simd_support & JSIMD_AVX2)
544     jsimd_h2v2_fancy_upsample_avx2(cinfo->max_v_samp_factor,
545                                    compptr->downsampled_width, input_data,
546                                    output_data_ptr);
547   else if (simd_support & JSIMD_SSE2)
548     jsimd_h2v2_fancy_upsample_sse2(cinfo->max_v_samp_factor,
549                                    compptr->downsampled_width, input_data,
550                                    output_data_ptr);
551   else
552     jsimd_h2v2_fancy_upsample_mmx(cinfo->max_v_samp_factor,
553                                   compptr->downsampled_width, input_data,
554                                   output_data_ptr);
555 }
556
557 GLOBAL(void)
558 jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
559                           JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
560 {
561   if (simd_support & JSIMD_AVX2)
562     jsimd_h2v1_fancy_upsample_avx2(cinfo->max_v_samp_factor,
563                                    compptr->downsampled_width, input_data,
564                                    output_data_ptr);
565   else if (simd_support & JSIMD_SSE2)
566     jsimd_h2v1_fancy_upsample_sse2(cinfo->max_v_samp_factor,
567                                    compptr->downsampled_width, input_data,
568                                    output_data_ptr);
569   else
570     jsimd_h2v1_fancy_upsample_mmx(cinfo->max_v_samp_factor,
571                                   compptr->downsampled_width, input_data,
572                                   output_data_ptr);
573 }
574
575 GLOBAL(int)
576 jsimd_can_h2v2_merged_upsample(void)
577 {
578   init_simd();
579
580   /* The code is optimised for these values only */
581   if (BITS_IN_JSAMPLE != 8)
582     return 0;
583   if (sizeof(JDIMENSION) != 4)
584     return 0;
585
586   if ((simd_support & JSIMD_AVX2) &&
587       IS_ALIGNED_AVX(jconst_merged_upsample_avx2))
588     return 1;
589   if ((simd_support & JSIMD_SSE2) &&
590       IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
591     return 1;
592   if (simd_support & JSIMD_MMX)
593     return 1;
594
595   return 0;
596 }
597
598 GLOBAL(int)
599 jsimd_can_h2v1_merged_upsample(void)
600 {
601   init_simd();
602
603   /* The code is optimised for these values only */
604   if (BITS_IN_JSAMPLE != 8)
605     return 0;
606   if (sizeof(JDIMENSION) != 4)
607     return 0;
608
609   if ((simd_support & JSIMD_AVX2) &&
610       IS_ALIGNED_AVX(jconst_merged_upsample_avx2))
611     return 1;
612   if ((simd_support & JSIMD_SSE2) &&
613       IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
614     return 1;
615   if (simd_support & JSIMD_MMX)
616     return 1;
617
618   return 0;
619 }
620
621 GLOBAL(void)
622 jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
623                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
624 {
625   void (*avx2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
626   void (*sse2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
627   void (*mmxfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
628
629   switch (cinfo->out_color_space) {
630   case JCS_EXT_RGB:
631     avx2fct = jsimd_h2v2_extrgb_merged_upsample_avx2;
632     sse2fct = jsimd_h2v2_extrgb_merged_upsample_sse2;
633     mmxfct = jsimd_h2v2_extrgb_merged_upsample_mmx;
634     break;
635   case JCS_EXT_RGBX:
636   case JCS_EXT_RGBA:
637     avx2fct = jsimd_h2v2_extrgbx_merged_upsample_avx2;
638     sse2fct = jsimd_h2v2_extrgbx_merged_upsample_sse2;
639     mmxfct = jsimd_h2v2_extrgbx_merged_upsample_mmx;
640     break;
641   case JCS_EXT_BGR:
642     avx2fct = jsimd_h2v2_extbgr_merged_upsample_avx2;
643     sse2fct = jsimd_h2v2_extbgr_merged_upsample_sse2;
644     mmxfct = jsimd_h2v2_extbgr_merged_upsample_mmx;
645     break;
646   case JCS_EXT_BGRX:
647   case JCS_EXT_BGRA:
648     avx2fct = jsimd_h2v2_extbgrx_merged_upsample_avx2;
649     sse2fct = jsimd_h2v2_extbgrx_merged_upsample_sse2;
650     mmxfct = jsimd_h2v2_extbgrx_merged_upsample_mmx;
651     break;
652   case JCS_EXT_XBGR:
653   case JCS_EXT_ABGR:
654     avx2fct = jsimd_h2v2_extxbgr_merged_upsample_avx2;
655     sse2fct = jsimd_h2v2_extxbgr_merged_upsample_sse2;
656     mmxfct = jsimd_h2v2_extxbgr_merged_upsample_mmx;
657     break;
658   case JCS_EXT_XRGB:
659   case JCS_EXT_ARGB:
660     avx2fct = jsimd_h2v2_extxrgb_merged_upsample_avx2;
661     sse2fct = jsimd_h2v2_extxrgb_merged_upsample_sse2;
662     mmxfct = jsimd_h2v2_extxrgb_merged_upsample_mmx;
663     break;
664   default:
665     avx2fct = jsimd_h2v2_merged_upsample_avx2;
666     sse2fct = jsimd_h2v2_merged_upsample_sse2;
667     mmxfct = jsimd_h2v2_merged_upsample_mmx;
668     break;
669   }
670
671   if (simd_support & JSIMD_AVX2)
672     avx2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
673   else if (simd_support & JSIMD_SSE2)
674     sse2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
675   else
676     mmxfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
677 }
678
679 GLOBAL(void)
680 jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
681                            JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
682 {
683   void (*avx2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
684   void (*sse2fct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
685   void (*mmxfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
686
687   switch (cinfo->out_color_space) {
688   case JCS_EXT_RGB:
689     avx2fct = jsimd_h2v1_extrgb_merged_upsample_avx2;
690     sse2fct = jsimd_h2v1_extrgb_merged_upsample_sse2;
691     mmxfct = jsimd_h2v1_extrgb_merged_upsample_mmx;
692     break;
693   case JCS_EXT_RGBX:
694   case JCS_EXT_RGBA:
695     avx2fct = jsimd_h2v1_extrgbx_merged_upsample_avx2;
696     sse2fct = jsimd_h2v1_extrgbx_merged_upsample_sse2;
697     mmxfct = jsimd_h2v1_extrgbx_merged_upsample_mmx;
698     break;
699   case JCS_EXT_BGR:
700     avx2fct = jsimd_h2v1_extbgr_merged_upsample_avx2;
701     sse2fct = jsimd_h2v1_extbgr_merged_upsample_sse2;
702     mmxfct = jsimd_h2v1_extbgr_merged_upsample_mmx;
703     break;
704   case JCS_EXT_BGRX:
705   case JCS_EXT_BGRA:
706     avx2fct = jsimd_h2v1_extbgrx_merged_upsample_avx2;
707     sse2fct = jsimd_h2v1_extbgrx_merged_upsample_sse2;
708     mmxfct = jsimd_h2v1_extbgrx_merged_upsample_mmx;
709     break;
710   case JCS_EXT_XBGR:
711   case JCS_EXT_ABGR:
712     avx2fct = jsimd_h2v1_extxbgr_merged_upsample_avx2;
713     sse2fct = jsimd_h2v1_extxbgr_merged_upsample_sse2;
714     mmxfct = jsimd_h2v1_extxbgr_merged_upsample_mmx;
715     break;
716   case JCS_EXT_XRGB:
717   case JCS_EXT_ARGB:
718     avx2fct = jsimd_h2v1_extxrgb_merged_upsample_avx2;
719     sse2fct = jsimd_h2v1_extxrgb_merged_upsample_sse2;
720     mmxfct = jsimd_h2v1_extxrgb_merged_upsample_mmx;
721     break;
722   default:
723     avx2fct = jsimd_h2v1_merged_upsample_avx2;
724     sse2fct = jsimd_h2v1_merged_upsample_sse2;
725     mmxfct = jsimd_h2v1_merged_upsample_mmx;
726     break;
727   }
728
729   if (simd_support & JSIMD_AVX2)
730     avx2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
731   else if (simd_support & JSIMD_SSE2)
732     sse2fct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
733   else
734     mmxfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
735 }
736
737 GLOBAL(int)
738 jsimd_can_convsamp(void)
739 {
740   init_simd();
741
742   /* The code is optimised for these values only */
743   if (DCTSIZE != 8)
744     return 0;
745   if (BITS_IN_JSAMPLE != 8)
746     return 0;
747   if (sizeof(JDIMENSION) != 4)
748     return 0;
749   if (sizeof(DCTELEM) != 2)
750     return 0;
751
752   if (simd_support & JSIMD_AVX2)
753     return 1;
754   if (simd_support & JSIMD_SSE2)
755     return 1;
756   if (simd_support & JSIMD_MMX)
757     return 1;
758
759   return 0;
760 }
761
762 GLOBAL(int)
763 jsimd_can_convsamp_float(void)
764 {
765   init_simd();
766
767   /* The code is optimised for these values only */
768   if (DCTSIZE != 8)
769     return 0;
770   if (BITS_IN_JSAMPLE != 8)
771     return 0;
772   if (sizeof(JDIMENSION) != 4)
773     return 0;
774   if (sizeof(FAST_FLOAT) != 4)
775     return 0;
776
777   if (simd_support & JSIMD_SSE2)
778     return 1;
779   if (simd_support & JSIMD_SSE)
780     return 1;
781   if (simd_support & JSIMD_3DNOW)
782     return 1;
783
784   return 0;
785 }
786
787 GLOBAL(void)
788 jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
789                DCTELEM *workspace)
790 {
791   if (simd_support & JSIMD_AVX2)
792     jsimd_convsamp_avx2(sample_data, start_col, workspace);
793   else if (simd_support & JSIMD_SSE2)
794     jsimd_convsamp_sse2(sample_data, start_col, workspace);
795   else
796     jsimd_convsamp_mmx(sample_data, start_col, workspace);
797 }
798
799 GLOBAL(void)
800 jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
801                      FAST_FLOAT *workspace)
802 {
803   if (simd_support & JSIMD_SSE2)
804     jsimd_convsamp_float_sse2(sample_data, start_col, workspace);
805   else if (simd_support & JSIMD_SSE)
806     jsimd_convsamp_float_sse(sample_data, start_col, workspace);
807   else
808     jsimd_convsamp_float_3dnow(sample_data, start_col, workspace);
809 }
810
811 GLOBAL(int)
812 jsimd_can_fdct_islow(void)
813 {
814   init_simd();
815
816   /* The code is optimised for these values only */
817   if (DCTSIZE != 8)
818     return 0;
819   if (sizeof(DCTELEM) != 2)
820     return 0;
821
822   if ((simd_support & JSIMD_AVX2) && IS_ALIGNED_AVX(jconst_fdct_islow_avx2))
823     return 1;
824   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
825     return 1;
826   if (simd_support & JSIMD_MMX)
827     return 1;
828
829   return 0;
830 }
831
832 GLOBAL(int)
833 jsimd_can_fdct_ifast(void)
834 {
835   init_simd();
836
837   /* The code is optimised for these values only */
838   if (DCTSIZE != 8)
839     return 0;
840   if (sizeof(DCTELEM) != 2)
841     return 0;
842
843   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_ifast_sse2))
844     return 1;
845   if (simd_support & JSIMD_MMX)
846     return 1;
847
848   return 0;
849 }
850
851 GLOBAL(int)
852 jsimd_can_fdct_float(void)
853 {
854   init_simd();
855
856   /* The code is optimised for these values only */
857   if (DCTSIZE != 8)
858     return 0;
859   if (sizeof(FAST_FLOAT) != 4)
860     return 0;
861
862   if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_fdct_float_sse))
863     return 1;
864   if (simd_support & JSIMD_3DNOW)
865     return 1;
866
867   return 0;
868 }
869
870 GLOBAL(void)
871 jsimd_fdct_islow(DCTELEM *data)
872 {
873   if (simd_support & JSIMD_AVX2)
874     jsimd_fdct_islow_avx2(data);
875   else if (simd_support & JSIMD_SSE2)
876     jsimd_fdct_islow_sse2(data);
877   else
878     jsimd_fdct_islow_mmx(data);
879 }
880
881 GLOBAL(void)
882 jsimd_fdct_ifast(DCTELEM *data)
883 {
884   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
885     jsimd_fdct_ifast_sse2(data);
886   else
887     jsimd_fdct_ifast_mmx(data);
888 }
889
890 GLOBAL(void)
891 jsimd_fdct_float(FAST_FLOAT *data)
892 {
893   if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_fdct_float_sse))
894     jsimd_fdct_float_sse(data);
895   else if (simd_support & JSIMD_3DNOW)
896     jsimd_fdct_float_3dnow(data);
897 }
898
899 GLOBAL(int)
900 jsimd_can_quantize(void)
901 {
902   init_simd();
903
904   /* The code is optimised for these values only */
905   if (DCTSIZE != 8)
906     return 0;
907   if (sizeof(JCOEF) != 2)
908     return 0;
909   if (sizeof(DCTELEM) != 2)
910     return 0;
911
912   if (simd_support & JSIMD_AVX2)
913     return 1;
914   if (simd_support & JSIMD_SSE2)
915     return 1;
916   if (simd_support & JSIMD_MMX)
917     return 1;
918
919   return 0;
920 }
921
922 GLOBAL(int)
923 jsimd_can_quantize_float(void)
924 {
925   init_simd();
926
927   /* The code is optimised for these values only */
928   if (DCTSIZE != 8)
929     return 0;
930   if (sizeof(JCOEF) != 2)
931     return 0;
932   if (sizeof(FAST_FLOAT) != 4)
933     return 0;
934
935   if (simd_support & JSIMD_SSE2)
936     return 1;
937   if (simd_support & JSIMD_SSE)
938     return 1;
939   if (simd_support & JSIMD_3DNOW)
940     return 1;
941
942   return 0;
943 }
944
945 GLOBAL(void)
946 jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
947 {
948   if (simd_support & JSIMD_AVX2)
949     jsimd_quantize_avx2(coef_block, divisors, workspace);
950   else if (simd_support & JSIMD_SSE2)
951     jsimd_quantize_sse2(coef_block, divisors, workspace);
952   else
953     jsimd_quantize_mmx(coef_block, divisors, workspace);
954 }
955
956 GLOBAL(void)
957 jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
958                      FAST_FLOAT *workspace)
959 {
960   if (simd_support & JSIMD_SSE2)
961     jsimd_quantize_float_sse2(coef_block, divisors, workspace);
962   else if (simd_support & JSIMD_SSE)
963     jsimd_quantize_float_sse(coef_block, divisors, workspace);
964   else
965     jsimd_quantize_float_3dnow(coef_block, divisors, workspace);
966 }
967
968 GLOBAL(int)
969 jsimd_can_idct_2x2(void)
970 {
971   init_simd();
972
973   /* The code is optimised for these values only */
974   if (DCTSIZE != 8)
975     return 0;
976   if (sizeof(JCOEF) != 2)
977     return 0;
978   if (BITS_IN_JSAMPLE != 8)
979     return 0;
980   if (sizeof(JDIMENSION) != 4)
981     return 0;
982   if (sizeof(ISLOW_MULT_TYPE) != 2)
983     return 0;
984
985   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
986     return 1;
987   if (simd_support & JSIMD_MMX)
988     return 1;
989
990   return 0;
991 }
992
993 GLOBAL(int)
994 jsimd_can_idct_4x4(void)
995 {
996   init_simd();
997
998   /* The code is optimised for these values only */
999   if (DCTSIZE != 8)
1000     return 0;
1001   if (sizeof(JCOEF) != 2)
1002     return 0;
1003   if (BITS_IN_JSAMPLE != 8)
1004     return 0;
1005   if (sizeof(JDIMENSION) != 4)
1006     return 0;
1007   if (sizeof(ISLOW_MULT_TYPE) != 2)
1008     return 0;
1009
1010   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
1011     return 1;
1012   if (simd_support & JSIMD_MMX)
1013     return 1;
1014
1015   return 0;
1016 }
1017
1018 GLOBAL(void)
1019 jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1020                JCOEFPTR coef_block, JSAMPARRAY output_buf,
1021                JDIMENSION output_col)
1022 {
1023   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
1024     jsimd_idct_2x2_sse2(compptr->dct_table, coef_block, output_buf,
1025                         output_col);
1026   else
1027     jsimd_idct_2x2_mmx(compptr->dct_table, coef_block, output_buf, output_col);
1028 }
1029
1030 GLOBAL(void)
1031 jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1032                JCOEFPTR coef_block, JSAMPARRAY output_buf,
1033                JDIMENSION output_col)
1034 {
1035   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
1036     jsimd_idct_4x4_sse2(compptr->dct_table, coef_block, output_buf,
1037                         output_col);
1038   else
1039     jsimd_idct_4x4_mmx(compptr->dct_table, coef_block, output_buf, output_col);
1040 }
1041
1042 GLOBAL(int)
1043 jsimd_can_idct_islow(void)
1044 {
1045   init_simd();
1046
1047   /* The code is optimised for these values only */
1048   if (DCTSIZE != 8)
1049     return 0;
1050   if (sizeof(JCOEF) != 2)
1051     return 0;
1052   if (BITS_IN_JSAMPLE != 8)
1053     return 0;
1054   if (sizeof(JDIMENSION) != 4)
1055     return 0;
1056   if (sizeof(ISLOW_MULT_TYPE) != 2)
1057     return 0;
1058
1059   if ((simd_support & JSIMD_AVX2) && IS_ALIGNED_AVX(jconst_idct_islow_avx2))
1060     return 1;
1061   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_islow_sse2))
1062     return 1;
1063   if (simd_support & JSIMD_MMX)
1064     return 1;
1065
1066   return 0;
1067 }
1068
1069 GLOBAL(int)
1070 jsimd_can_idct_ifast(void)
1071 {
1072   init_simd();
1073
1074   /* The code is optimised for these values only */
1075   if (DCTSIZE != 8)
1076     return 0;
1077   if (sizeof(JCOEF) != 2)
1078     return 0;
1079   if (BITS_IN_JSAMPLE != 8)
1080     return 0;
1081   if (sizeof(JDIMENSION) != 4)
1082     return 0;
1083   if (sizeof(IFAST_MULT_TYPE) != 2)
1084     return 0;
1085   if (IFAST_SCALE_BITS != 2)
1086     return 0;
1087
1088   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
1089     return 1;
1090   if (simd_support & JSIMD_MMX)
1091     return 1;
1092
1093   return 0;
1094 }
1095
1096 GLOBAL(int)
1097 jsimd_can_idct_float(void)
1098 {
1099   init_simd();
1100
1101   if (DCTSIZE != 8)
1102     return 0;
1103   if (sizeof(JCOEF) != 2)
1104     return 0;
1105   if (BITS_IN_JSAMPLE != 8)
1106     return 0;
1107   if (sizeof(JDIMENSION) != 4)
1108     return 0;
1109   if (sizeof(FAST_FLOAT) != 4)
1110     return 0;
1111   if (sizeof(FLOAT_MULT_TYPE) != 4)
1112     return 0;
1113
1114   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_float_sse2))
1115     return 1;
1116   if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_idct_float_sse))
1117     return 1;
1118   if (simd_support & JSIMD_3DNOW)
1119     return 1;
1120
1121   return 0;
1122 }
1123
1124 GLOBAL(void)
1125 jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1126                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1127                  JDIMENSION output_col)
1128 {
1129   if (simd_support & JSIMD_AVX2)
1130     jsimd_idct_islow_avx2(compptr->dct_table, coef_block, output_buf,
1131                           output_col);
1132   else if (simd_support & JSIMD_SSE2)
1133     jsimd_idct_islow_sse2(compptr->dct_table, coef_block, output_buf,
1134                           output_col);
1135   else
1136     jsimd_idct_islow_mmx(compptr->dct_table, coef_block, output_buf,
1137                          output_col);
1138 }
1139
1140 GLOBAL(void)
1141 jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1142                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1143                  JDIMENSION output_col)
1144 {
1145   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
1146     jsimd_idct_ifast_sse2(compptr->dct_table, coef_block, output_buf,
1147                           output_col);
1148   else
1149     jsimd_idct_ifast_mmx(compptr->dct_table, coef_block, output_buf,
1150                          output_col);
1151 }
1152
1153 GLOBAL(void)
1154 jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
1155                  JCOEFPTR coef_block, JSAMPARRAY output_buf,
1156                  JDIMENSION output_col)
1157 {
1158   if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_float_sse2))
1159     jsimd_idct_float_sse2(compptr->dct_table, coef_block, output_buf,
1160                           output_col);
1161   else if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_idct_float_sse))
1162     jsimd_idct_float_sse(compptr->dct_table, coef_block, output_buf,
1163                          output_col);
1164   else
1165     jsimd_idct_float_3dnow(compptr->dct_table, coef_block, output_buf,
1166                            output_col);
1167 }
1168
1169 GLOBAL(int)
1170 jsimd_can_huff_encode_one_block(void)
1171 {
1172   init_simd();
1173
1174   if (DCTSIZE != 8)
1175     return 0;
1176   if (sizeof(JCOEF) != 2)
1177     return 0;
1178
1179   if ((simd_support & JSIMD_SSE2) && simd_huffman &&
1180       IS_ALIGNED_SSE(jconst_huff_encode_one_block))
1181     return 1;
1182
1183   return 0;
1184 }
1185
1186 GLOBAL(JOCTET *)
1187 jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
1188                             int last_dc_val, c_derived_tbl *dctbl,
1189                             c_derived_tbl *actbl)
1190 {
1191   return jsimd_huff_encode_one_block_sse2(state, buffer, block, last_dc_val,
1192                                           dctbl, actbl);
1193 }
1194
1195 GLOBAL(int)
1196 jsimd_can_encode_mcu_AC_first_prepare(void)
1197 {
1198   init_simd();
1199
1200   if (DCTSIZE != 8)
1201     return 0;
1202   if (sizeof(JCOEF) != 2)
1203     return 0;
1204   if (SIZEOF_SIZE_T != 4)
1205     return 0;
1206   if (simd_support & JSIMD_SSE2)
1207     return 1;
1208
1209   return 0;
1210 }
1211
1212 GLOBAL(void)
1213 jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
1214                                   const int *jpeg_natural_order_start, int Sl,
1215                                   int Al, JCOEF *values, size_t *zerobits)
1216 {
1217   jsimd_encode_mcu_AC_first_prepare_sse2(block, jpeg_natural_order_start,
1218                                          Sl, Al, values, zerobits);
1219 }
1220
1221 GLOBAL(int)
1222 jsimd_can_encode_mcu_AC_refine_prepare(void)
1223 {
1224   init_simd();
1225
1226   if (DCTSIZE != 8)
1227     return 0;
1228   if (sizeof(JCOEF) != 2)
1229     return 0;
1230   if (SIZEOF_SIZE_T != 4)
1231     return 0;
1232   if (simd_support & JSIMD_SSE2)
1233     return 1;
1234
1235   return 0;
1236 }
1237
1238 GLOBAL(int)
1239 jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
1240                                    const int *jpeg_natural_order_start, int Sl,
1241                                    int Al, JCOEF *absvalues, size_t *bits)
1242 {
1243   return jsimd_encode_mcu_AC_refine_prepare_sse2(block,
1244                                                  jpeg_natural_order_start,
1245                                                  Sl, Al, absvalues, bits);
1246 }