1 : /*
2 : * jsimd_i386.c
3 : *
4 : * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5 : * Copyright 2009-2011 D. R. Commander
6 : *
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
10 : *
11 : * This file contains the interface between the "normal" portions
12 : * of the library and the SIMD implementations when running on a
13 : * 32-bit x86 architecture.
14 : */
15 :
16 : #define JPEG_INTERNALS
17 : #include "../jinclude.h"
18 : #include "../jpeglib.h"
19 : #include "../jsimd.h"
20 : #include "../jdct.h"
21 : #include "../jsimddct.h"
22 : #include "jsimd.h"
23 :
24 : /*
25 : * In the PIC cases, we have no guarantee that constants will keep
26 : * their alignment. This macro allows us to verify it at runtime.
27 : */
28 : #define IS_ALIGNED(ptr, order) (((unsigned)ptr & ((1 << order) - 1)) == 0)
29 :
30 : #define IS_ALIGNED_SSE(ptr) (IS_ALIGNED(ptr, 4)) /* 16 byte alignment */
31 :
32 : static unsigned int simd_support = ~0;
33 :
34 : /*
35 : * Check what SIMD accelerations are supported.
36 : *
37 : * FIXME: This code is racy under a multi-threaded environment.
38 : */
39 : LOCAL(void)
40 42 : init_simd (void)
41 : {
42 42 : char *env = NULL;
43 :
44 42 : if (simd_support != ~0U)
45 40 : return;
46 :
47 2 : simd_support = jpeg_simd_cpu_support();
48 :
49 : /* Force different settings through environment variables */
50 2 : env = getenv("JSIMD_FORCEMMX");
51 2 : if ((env != NULL) && (strcmp(env, "1") == 0))
52 0 : simd_support &= JSIMD_MMX;
53 2 : env = getenv("JSIMD_FORCE3DNOW");
54 2 : if ((env != NULL) && (strcmp(env, "1") == 0))
55 0 : simd_support &= JSIMD_3DNOW|JSIMD_MMX;
56 2 : env = getenv("JSIMD_FORCESSE");
57 2 : if ((env != NULL) && (strcmp(env, "1") == 0))
58 0 : simd_support &= JSIMD_SSE|JSIMD_MMX;
59 2 : env = getenv("JSIMD_FORCESSE2");
60 2 : if ((env != NULL) && (strcmp(env, "1") == 0))
61 0 : simd_support &= JSIMD_SSE2;
62 : }
63 :
64 : GLOBAL(int)
65 3 : jsimd_can_rgb_ycc (void)
66 : {
67 3 : init_simd();
68 :
69 : /* The code is optimised for these values only */
70 : if (BITS_IN_JSAMPLE != 8)
71 : return 0;
72 : if (sizeof(JDIMENSION) != 4)
73 : return 0;
74 : if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
75 : return 0;
76 :
77 6 : if ((simd_support & JSIMD_SSE2) &&
78 3 : IS_ALIGNED_SSE(jconst_rgb_ycc_convert_sse2))
79 3 : return 1;
80 0 : if (simd_support & JSIMD_MMX)
81 0 : return 1;
82 :
83 0 : return 0;
84 : }
85 :
86 : GLOBAL(int)
87 0 : jsimd_can_rgb_gray (void)
88 : {
89 0 : init_simd();
90 :
91 : /* The code is optimised for these values only */
92 : if (BITS_IN_JSAMPLE != 8)
93 : return 0;
94 : if (sizeof(JDIMENSION) != 4)
95 : return 0;
96 : if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
97 : return 0;
98 :
99 0 : if ((simd_support & JSIMD_SSE2) &&
100 0 : IS_ALIGNED_SSE(jconst_rgb_gray_convert_sse2))
101 0 : return 1;
102 0 : if (simd_support & JSIMD_MMX)
103 0 : return 1;
104 :
105 0 : return 0;
106 : }
107 :
108 : GLOBAL(int)
109 5 : jsimd_can_ycc_rgb (void)
110 : {
111 5 : init_simd();
112 :
113 : /* The code is optimised for these values only */
114 : if (BITS_IN_JSAMPLE != 8)
115 : return 0;
116 : if (sizeof(JDIMENSION) != 4)
117 : return 0;
118 : if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
119 : return 0;
120 :
121 10 : if ((simd_support & JSIMD_SSE2) &&
122 5 : IS_ALIGNED_SSE(jconst_ycc_rgb_convert_sse2))
123 5 : return 1;
124 0 : if (simd_support & JSIMD_MMX)
125 0 : return 1;
126 :
127 0 : return 0;
128 : }
129 :
130 : GLOBAL(void)
131 144 : jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
132 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
133 : JDIMENSION output_row, int num_rows)
134 : {
135 : void (*sse2fct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
136 : void (*mmxfct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
137 :
138 144 : switch(cinfo->in_color_space)
139 : {
140 : case JCS_EXT_RGB:
141 0 : sse2fct=jsimd_extrgb_ycc_convert_sse2;
142 0 : mmxfct=jsimd_extrgb_ycc_convert_mmx;
143 0 : break;
144 : case JCS_EXT_RGBX:
145 : case JCS_EXT_RGBA:
146 0 : sse2fct=jsimd_extrgbx_ycc_convert_sse2;
147 0 : mmxfct=jsimd_extrgbx_ycc_convert_mmx;
148 0 : break;
149 : case JCS_EXT_BGR:
150 0 : sse2fct=jsimd_extbgr_ycc_convert_sse2;
151 0 : mmxfct=jsimd_extbgr_ycc_convert_mmx;
152 0 : break;
153 : case JCS_EXT_BGRX:
154 : case JCS_EXT_BGRA:
155 0 : sse2fct=jsimd_extbgrx_ycc_convert_sse2;
156 0 : mmxfct=jsimd_extbgrx_ycc_convert_mmx;
157 0 : break;
158 : case JCS_EXT_XBGR:
159 : case JCS_EXT_ABGR:
160 0 : sse2fct=jsimd_extxbgr_ycc_convert_sse2;
161 0 : mmxfct=jsimd_extxbgr_ycc_convert_mmx;
162 0 : break;
163 : case JCS_EXT_XRGB:
164 : case JCS_EXT_ARGB:
165 0 : sse2fct=jsimd_extxrgb_ycc_convert_sse2;
166 0 : mmxfct=jsimd_extxrgb_ycc_convert_mmx;
167 0 : break;
168 : default:
169 144 : sse2fct=jsimd_rgb_ycc_convert_sse2;
170 144 : mmxfct=jsimd_rgb_ycc_convert_mmx;
171 144 : break;
172 : }
173 :
174 288 : if ((simd_support & JSIMD_SSE2) &&
175 144 : IS_ALIGNED_SSE(jconst_rgb_ycc_convert_sse2))
176 144 : sse2fct(cinfo->image_width, input_buf,
177 : output_buf, output_row, num_rows);
178 0 : else if (simd_support & JSIMD_MMX)
179 0 : mmxfct(cinfo->image_width, input_buf,
180 : output_buf, output_row, num_rows);
181 144 : }
182 :
183 : GLOBAL(void)
184 0 : jsimd_rgb_gray_convert (j_compress_ptr cinfo,
185 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
186 : JDIMENSION output_row, int num_rows)
187 : {
188 : void (*sse2fct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
189 : void (*mmxfct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
190 :
191 0 : switch(cinfo->in_color_space)
192 : {
193 : case JCS_EXT_RGB:
194 0 : sse2fct=jsimd_extrgb_gray_convert_sse2;
195 0 : mmxfct=jsimd_extrgb_gray_convert_mmx;
196 0 : break;
197 : case JCS_EXT_RGBX:
198 : case JCS_EXT_RGBA:
199 0 : sse2fct=jsimd_extrgbx_gray_convert_sse2;
200 0 : mmxfct=jsimd_extrgbx_gray_convert_mmx;
201 0 : break;
202 : case JCS_EXT_BGR:
203 0 : sse2fct=jsimd_extbgr_gray_convert_sse2;
204 0 : mmxfct=jsimd_extbgr_gray_convert_mmx;
205 0 : break;
206 : case JCS_EXT_BGRX:
207 : case JCS_EXT_BGRA:
208 0 : sse2fct=jsimd_extbgrx_gray_convert_sse2;
209 0 : mmxfct=jsimd_extbgrx_gray_convert_mmx;
210 0 : break;
211 : case JCS_EXT_XBGR:
212 : case JCS_EXT_ABGR:
213 0 : sse2fct=jsimd_extxbgr_gray_convert_sse2;
214 0 : mmxfct=jsimd_extxbgr_gray_convert_mmx;
215 0 : break;
216 : case JCS_EXT_XRGB:
217 : case JCS_EXT_ARGB:
218 0 : sse2fct=jsimd_extxrgb_gray_convert_sse2;
219 0 : mmxfct=jsimd_extxrgb_gray_convert_mmx;
220 0 : break;
221 : default:
222 0 : sse2fct=jsimd_rgb_gray_convert_sse2;
223 0 : mmxfct=jsimd_rgb_gray_convert_mmx;
224 0 : break;
225 : }
226 :
227 0 : if ((simd_support & JSIMD_SSE2) &&
228 0 : IS_ALIGNED_SSE(jconst_rgb_gray_convert_sse2))
229 0 : sse2fct(cinfo->image_width, input_buf,
230 : output_buf, output_row, num_rows);
231 0 : else if (simd_support & JSIMD_MMX)
232 0 : mmxfct(cinfo->image_width, input_buf,
233 : output_buf, output_row, num_rows);
234 0 : }
235 :
236 : GLOBAL(void)
237 0 : jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
238 : JSAMPIMAGE input_buf, JDIMENSION input_row,
239 : JSAMPARRAY output_buf, int num_rows)
240 : {
241 : void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
242 : void (*mmxfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
243 :
244 0 : switch(cinfo->out_color_space)
245 : {
246 : case JCS_EXT_RGB:
247 0 : sse2fct=jsimd_ycc_extrgb_convert_sse2;
248 0 : mmxfct=jsimd_ycc_extrgb_convert_mmx;
249 0 : break;
250 : case JCS_EXT_RGBX:
251 : case JCS_EXT_RGBA:
252 0 : sse2fct=jsimd_ycc_extrgbx_convert_sse2;
253 0 : mmxfct=jsimd_ycc_extrgbx_convert_mmx;
254 0 : break;
255 : case JCS_EXT_BGR:
256 0 : sse2fct=jsimd_ycc_extbgr_convert_sse2;
257 0 : mmxfct=jsimd_ycc_extbgr_convert_mmx;
258 0 : break;
259 : case JCS_EXT_BGRX:
260 : case JCS_EXT_BGRA:
261 0 : sse2fct=jsimd_ycc_extbgrx_convert_sse2;
262 0 : mmxfct=jsimd_ycc_extbgrx_convert_mmx;
263 0 : break;
264 : case JCS_EXT_XBGR:
265 : case JCS_EXT_ABGR:
266 0 : sse2fct=jsimd_ycc_extxbgr_convert_sse2;
267 0 : mmxfct=jsimd_ycc_extxbgr_convert_mmx;
268 0 : break;
269 : case JCS_EXT_XRGB:
270 : case JCS_EXT_ARGB:
271 0 : sse2fct=jsimd_ycc_extxrgb_convert_sse2;
272 0 : mmxfct=jsimd_ycc_extxrgb_convert_mmx;
273 0 : break;
274 : default:
275 0 : sse2fct=jsimd_ycc_rgb_convert_sse2;
276 0 : mmxfct=jsimd_ycc_rgb_convert_mmx;
277 0 : break;
278 : }
279 :
280 0 : if ((simd_support & JSIMD_SSE2) &&
281 0 : IS_ALIGNED_SSE(jconst_ycc_rgb_convert_sse2))
282 0 : sse2fct(cinfo->output_width, input_buf,
283 : input_row, output_buf, num_rows);
284 0 : else if (simd_support & JSIMD_MMX)
285 0 : mmxfct(cinfo->output_width, input_buf,
286 : input_row, output_buf, num_rows);
287 0 : }
288 :
289 : GLOBAL(int)
290 0 : jsimd_can_h2v2_downsample (void)
291 : {
292 0 : init_simd();
293 :
294 : /* The code is optimised for these values only */
295 : if (BITS_IN_JSAMPLE != 8)
296 : return 0;
297 : if (sizeof(JDIMENSION) != 4)
298 : return 0;
299 :
300 0 : if (simd_support & JSIMD_SSE2)
301 0 : return 1;
302 0 : if (simd_support & JSIMD_MMX)
303 0 : return 1;
304 :
305 0 : return 0;
306 : }
307 :
308 : GLOBAL(int)
309 0 : jsimd_can_h2v1_downsample (void)
310 : {
311 0 : init_simd();
312 :
313 : /* The code is optimised for these values only */
314 : if (BITS_IN_JSAMPLE != 8)
315 : return 0;
316 : if (sizeof(JDIMENSION) != 4)
317 : return 0;
318 :
319 0 : if (simd_support & JSIMD_SSE2)
320 0 : return 1;
321 0 : if (simd_support & JSIMD_MMX)
322 0 : return 1;
323 :
324 0 : return 0;
325 : }
326 :
327 : GLOBAL(void)
328 0 : jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
329 : JSAMPARRAY input_data, JSAMPARRAY output_data)
330 : {
331 0 : if (simd_support & JSIMD_SSE2)
332 0 : jsimd_h2v2_downsample_sse2(cinfo->image_width, cinfo->max_v_samp_factor,
333 0 : compptr->v_samp_factor, compptr->width_in_blocks,
334 : input_data, output_data);
335 0 : else if (simd_support & JSIMD_MMX)
336 0 : jsimd_h2v2_downsample_mmx(cinfo->image_width, cinfo->max_v_samp_factor,
337 0 : compptr->v_samp_factor, compptr->width_in_blocks,
338 : input_data, output_data);
339 0 : }
340 :
341 : GLOBAL(void)
342 0 : jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
343 : JSAMPARRAY input_data, JSAMPARRAY output_data)
344 : {
345 0 : if (simd_support & JSIMD_SSE2)
346 0 : jsimd_h2v1_downsample_sse2(cinfo->image_width, cinfo->max_v_samp_factor,
347 0 : compptr->v_samp_factor, compptr->width_in_blocks,
348 : input_data, output_data);
349 0 : else if (simd_support & JSIMD_MMX)
350 0 : jsimd_h2v1_downsample_mmx(cinfo->image_width, cinfo->max_v_samp_factor,
351 0 : compptr->v_samp_factor, compptr->width_in_blocks,
352 : input_data, output_data);
353 0 : }
354 :
355 : GLOBAL(int)
356 4 : jsimd_can_h2v2_upsample (void)
357 : {
358 4 : init_simd();
359 :
360 : /* The code is optimised for these values only */
361 : if (BITS_IN_JSAMPLE != 8)
362 : return 0;
363 : if (sizeof(JDIMENSION) != 4)
364 : return 0;
365 :
366 4 : if (simd_support & JSIMD_SSE2)
367 4 : return 1;
368 0 : if (simd_support & JSIMD_MMX)
369 0 : return 1;
370 :
371 0 : return 0;
372 : }
373 :
374 : GLOBAL(int)
375 0 : jsimd_can_h2v1_upsample (void)
376 : {
377 0 : init_simd();
378 :
379 : /* The code is optimised for these values only */
380 : if (BITS_IN_JSAMPLE != 8)
381 : return 0;
382 : if (sizeof(JDIMENSION) != 4)
383 : return 0;
384 :
385 0 : if (simd_support & JSIMD_SSE2)
386 0 : return 1;
387 0 : if (simd_support & JSIMD_MMX)
388 0 : return 1;
389 :
390 0 : return 0;
391 : }
392 :
393 : GLOBAL(void)
394 164 : jsimd_h2v2_upsample (j_decompress_ptr cinfo,
395 : jpeg_component_info * compptr,
396 : JSAMPARRAY input_data,
397 : JSAMPARRAY * output_data_ptr)
398 : {
399 164 : if (simd_support & JSIMD_SSE2)
400 164 : jsimd_h2v2_upsample_sse2(cinfo->max_v_samp_factor,
401 : cinfo->output_width, input_data, output_data_ptr);
402 0 : else if (simd_support & JSIMD_MMX)
403 0 : jsimd_h2v2_upsample_mmx(cinfo->max_v_samp_factor,
404 : cinfo->output_width, input_data, output_data_ptr);
405 164 : }
406 :
407 : GLOBAL(void)
408 0 : jsimd_h2v1_upsample (j_decompress_ptr cinfo,
409 : jpeg_component_info * compptr,
410 : JSAMPARRAY input_data,
411 : JSAMPARRAY * output_data_ptr)
412 : {
413 0 : if (simd_support & JSIMD_SSE2)
414 0 : jsimd_h2v1_upsample_sse2(cinfo->max_v_samp_factor,
415 : cinfo->output_width, input_data, output_data_ptr);
416 0 : else if (simd_support & JSIMD_MMX)
417 0 : jsimd_h2v1_upsample_mmx(cinfo->max_v_samp_factor,
418 : cinfo->output_width, input_data, output_data_ptr);
419 0 : }
420 :
421 : GLOBAL(int)
422 6 : jsimd_can_h2v2_fancy_upsample (void)
423 : {
424 6 : 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 12 : if ((simd_support & JSIMD_SSE2) &&
433 6 : IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
434 6 : return 1;
435 0 : if (simd_support & JSIMD_MMX)
436 0 : return 1;
437 :
438 0 : return 0;
439 : }
440 :
441 : GLOBAL(int)
442 0 : jsimd_can_h2v1_fancy_upsample (void)
443 : {
444 0 : init_simd();
445 :
446 : /* The code is optimised for these values only */
447 : if (BITS_IN_JSAMPLE != 8)
448 : return 0;
449 : if (sizeof(JDIMENSION) != 4)
450 : return 0;
451 :
452 0 : if ((simd_support & JSIMD_SSE2) &&
453 0 : IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
454 0 : return 1;
455 0 : if (simd_support & JSIMD_MMX)
456 0 : return 1;
457 :
458 0 : return 0;
459 : }
460 :
461 : GLOBAL(void)
462 68 : jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
463 : jpeg_component_info * compptr,
464 : JSAMPARRAY input_data,
465 : JSAMPARRAY * output_data_ptr)
466 : {
467 136 : if ((simd_support & JSIMD_SSE2) &&
468 68 : IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
469 68 : jsimd_h2v2_fancy_upsample_sse2(cinfo->max_v_samp_factor,
470 : compptr->downsampled_width, input_data, output_data_ptr);
471 0 : else if (simd_support & JSIMD_MMX)
472 0 : jsimd_h2v2_fancy_upsample_mmx(cinfo->max_v_samp_factor,
473 : compptr->downsampled_width, input_data, output_data_ptr);
474 68 : }
475 :
476 : GLOBAL(void)
477 0 : jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
478 : jpeg_component_info * compptr,
479 : JSAMPARRAY input_data,
480 : JSAMPARRAY * output_data_ptr)
481 : {
482 0 : if ((simd_support & JSIMD_SSE2) &&
483 0 : IS_ALIGNED_SSE(jconst_fancy_upsample_sse2))
484 0 : jsimd_h2v1_fancy_upsample_sse2(cinfo->max_v_samp_factor,
485 : compptr->downsampled_width, input_data, output_data_ptr);
486 0 : else if (simd_support & JSIMD_MMX)
487 0 : jsimd_h2v1_fancy_upsample_mmx(cinfo->max_v_samp_factor,
488 : compptr->downsampled_width, input_data, output_data_ptr);
489 0 : }
490 :
491 : GLOBAL(int)
492 0 : jsimd_can_h2v2_merged_upsample (void)
493 : {
494 0 : init_simd();
495 :
496 : /* The code is optimised for these values only */
497 : if (BITS_IN_JSAMPLE != 8)
498 : return 0;
499 : if (sizeof(JDIMENSION) != 4)
500 : return 0;
501 :
502 0 : if ((simd_support & JSIMD_SSE2) &&
503 0 : IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
504 0 : return 1;
505 0 : if (simd_support & JSIMD_MMX)
506 0 : return 1;
507 :
508 0 : return 0;
509 : }
510 :
511 : GLOBAL(int)
512 0 : jsimd_can_h2v1_merged_upsample (void)
513 : {
514 0 : init_simd();
515 :
516 : /* The code is optimised for these values only */
517 : if (BITS_IN_JSAMPLE != 8)
518 : return 0;
519 : if (sizeof(JDIMENSION) != 4)
520 : return 0;
521 :
522 0 : if ((simd_support & JSIMD_SSE2) &&
523 0 : IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
524 0 : return 1;
525 0 : if (simd_support & JSIMD_MMX)
526 0 : return 1;
527 :
528 0 : return 0;
529 : }
530 :
531 : GLOBAL(void)
532 0 : jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
533 : JSAMPIMAGE input_buf,
534 : JDIMENSION in_row_group_ctr,
535 : JSAMPARRAY output_buf)
536 : {
537 : void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
538 : void (*mmxfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
539 :
540 0 : switch(cinfo->out_color_space)
541 : {
542 : case JCS_EXT_RGB:
543 0 : sse2fct=jsimd_h2v2_extrgb_merged_upsample_sse2;
544 0 : mmxfct=jsimd_h2v2_extrgb_merged_upsample_mmx;
545 0 : break;
546 : case JCS_EXT_RGBX:
547 : case JCS_EXT_RGBA:
548 0 : sse2fct=jsimd_h2v2_extrgbx_merged_upsample_sse2;
549 0 : mmxfct=jsimd_h2v2_extrgbx_merged_upsample_mmx;
550 0 : break;
551 : case JCS_EXT_BGR:
552 0 : sse2fct=jsimd_h2v2_extbgr_merged_upsample_sse2;
553 0 : mmxfct=jsimd_h2v2_extbgr_merged_upsample_mmx;
554 0 : break;
555 : case JCS_EXT_BGRX:
556 : case JCS_EXT_BGRA:
557 0 : sse2fct=jsimd_h2v2_extbgrx_merged_upsample_sse2;
558 0 : mmxfct=jsimd_h2v2_extbgrx_merged_upsample_mmx;
559 0 : break;
560 : case JCS_EXT_XBGR:
561 : case JCS_EXT_ABGR:
562 0 : sse2fct=jsimd_h2v2_extxbgr_merged_upsample_sse2;
563 0 : mmxfct=jsimd_h2v2_extxbgr_merged_upsample_mmx;
564 0 : break;
565 : case JCS_EXT_XRGB:
566 : case JCS_EXT_ARGB:
567 0 : sse2fct=jsimd_h2v2_extxrgb_merged_upsample_sse2;
568 0 : mmxfct=jsimd_h2v2_extxrgb_merged_upsample_mmx;
569 0 : break;
570 : default:
571 0 : sse2fct=jsimd_h2v2_merged_upsample_sse2;
572 0 : mmxfct=jsimd_h2v2_merged_upsample_mmx;
573 0 : break;
574 : }
575 :
576 0 : if ((simd_support & JSIMD_SSE2) &&
577 0 : IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
578 0 : sse2fct(cinfo->output_width, input_buf,
579 : in_row_group_ctr, output_buf);
580 0 : else if (simd_support & JSIMD_MMX)
581 0 : mmxfct(cinfo->output_width, input_buf,
582 : in_row_group_ctr, output_buf);
583 0 : }
584 :
585 : GLOBAL(void)
586 0 : jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
587 : JSAMPIMAGE input_buf,
588 : JDIMENSION in_row_group_ctr,
589 : JSAMPARRAY output_buf)
590 : {
591 : void (*sse2fct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
592 : void (*mmxfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
593 :
594 0 : switch(cinfo->out_color_space)
595 : {
596 : case JCS_EXT_RGB:
597 0 : sse2fct=jsimd_h2v1_extrgb_merged_upsample_sse2;
598 0 : mmxfct=jsimd_h2v1_extrgb_merged_upsample_mmx;
599 0 : break;
600 : case JCS_EXT_RGBX:
601 : case JCS_EXT_RGBA:
602 0 : sse2fct=jsimd_h2v1_extrgbx_merged_upsample_sse2;
603 0 : mmxfct=jsimd_h2v1_extrgbx_merged_upsample_mmx;
604 0 : break;
605 : case JCS_EXT_BGR:
606 0 : sse2fct=jsimd_h2v1_extbgr_merged_upsample_sse2;
607 0 : mmxfct=jsimd_h2v1_extbgr_merged_upsample_mmx;
608 0 : break;
609 : case JCS_EXT_BGRX:
610 : case JCS_EXT_BGRA:
611 0 : sse2fct=jsimd_h2v1_extbgrx_merged_upsample_sse2;
612 0 : mmxfct=jsimd_h2v1_extbgrx_merged_upsample_mmx;
613 0 : break;
614 : case JCS_EXT_XBGR:
615 : case JCS_EXT_ABGR:
616 0 : sse2fct=jsimd_h2v1_extxbgr_merged_upsample_sse2;
617 0 : mmxfct=jsimd_h2v1_extxbgr_merged_upsample_mmx;
618 0 : break;
619 : case JCS_EXT_XRGB:
620 : case JCS_EXT_ARGB:
621 0 : sse2fct=jsimd_h2v1_extxrgb_merged_upsample_sse2;
622 0 : mmxfct=jsimd_h2v1_extxrgb_merged_upsample_mmx;
623 0 : break;
624 : default:
625 0 : sse2fct=jsimd_h2v1_merged_upsample_sse2;
626 0 : mmxfct=jsimd_h2v1_merged_upsample_mmx;
627 0 : break;
628 : }
629 :
630 0 : if ((simd_support & JSIMD_SSE2) &&
631 0 : IS_ALIGNED_SSE(jconst_merged_upsample_sse2))
632 0 : sse2fct(cinfo->output_width, input_buf,
633 : in_row_group_ctr, output_buf);
634 0 : else if (simd_support & JSIMD_MMX)
635 0 : mmxfct(cinfo->output_width, input_buf,
636 : in_row_group_ctr, output_buf);
637 0 : }
638 :
639 : GLOBAL(int)
640 3 : jsimd_can_convsamp (void)
641 : {
642 3 : init_simd();
643 :
644 : /* The code is optimised for these values only */
645 : if (DCTSIZE != 8)
646 : return 0;
647 : if (BITS_IN_JSAMPLE != 8)
648 : return 0;
649 : if (sizeof(JDIMENSION) != 4)
650 : return 0;
651 : if (sizeof(DCTELEM) != 2)
652 : return 0;
653 :
654 3 : if (simd_support & JSIMD_SSE2)
655 3 : return 1;
656 0 : if (simd_support & JSIMD_MMX)
657 0 : return 1;
658 :
659 0 : return 0;
660 : }
661 :
662 : GLOBAL(int)
663 0 : jsimd_can_convsamp_float (void)
664 : {
665 0 : init_simd();
666 :
667 : /* The code is optimised for these values only */
668 : if (DCTSIZE != 8)
669 : return 0;
670 : if (BITS_IN_JSAMPLE != 8)
671 : return 0;
672 : if (sizeof(JDIMENSION) != 4)
673 : return 0;
674 : if (sizeof(FAST_FLOAT) != 4)
675 : return 0;
676 :
677 0 : if (simd_support & JSIMD_SSE2)
678 0 : return 1;
679 0 : if (simd_support & JSIMD_SSE)
680 0 : return 1;
681 0 : if (simd_support & JSIMD_3DNOW)
682 0 : return 1;
683 :
684 0 : return 0;
685 : }
686 :
687 : GLOBAL(void)
688 396 : jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
689 : DCTELEM * workspace)
690 : {
691 396 : if (simd_support & JSIMD_SSE2)
692 396 : jsimd_convsamp_sse2(sample_data, start_col, workspace);
693 0 : else if (simd_support & JSIMD_MMX)
694 0 : jsimd_convsamp_mmx(sample_data, start_col, workspace);
695 396 : }
696 :
697 : GLOBAL(void)
698 0 : jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
699 : FAST_FLOAT * workspace)
700 : {
701 0 : if (simd_support & JSIMD_SSE2)
702 0 : jsimd_convsamp_float_sse2(sample_data, start_col, workspace);
703 0 : else if (simd_support & JSIMD_SSE)
704 0 : jsimd_convsamp_float_sse(sample_data, start_col, workspace);
705 0 : else if (simd_support & JSIMD_3DNOW)
706 0 : jsimd_convsamp_float_3dnow(sample_data, start_col, workspace);
707 0 : }
708 :
709 : GLOBAL(int)
710 3 : jsimd_can_fdct_islow (void)
711 : {
712 3 : init_simd();
713 :
714 : /* The code is optimised for these values only */
715 : if (DCTSIZE != 8)
716 : return 0;
717 : if (sizeof(DCTELEM) != 2)
718 : return 0;
719 :
720 3 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
721 3 : return 1;
722 0 : if (simd_support & JSIMD_MMX)
723 0 : return 1;
724 :
725 0 : return 0;
726 : }
727 :
728 : GLOBAL(int)
729 0 : jsimd_can_fdct_ifast (void)
730 : {
731 0 : init_simd();
732 :
733 : /* The code is optimised for these values only */
734 : if (DCTSIZE != 8)
735 : return 0;
736 : if (sizeof(DCTELEM) != 2)
737 : return 0;
738 :
739 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_ifast_sse2))
740 0 : return 1;
741 0 : if (simd_support & JSIMD_MMX)
742 0 : return 1;
743 :
744 0 : return 0;
745 : }
746 :
747 : GLOBAL(int)
748 0 : jsimd_can_fdct_float (void)
749 : {
750 0 : init_simd();
751 :
752 : /* The code is optimised for these values only */
753 : if (DCTSIZE != 8)
754 : return 0;
755 : if (sizeof(FAST_FLOAT) != 4)
756 : return 0;
757 :
758 0 : if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_fdct_float_sse))
759 0 : return 1;
760 0 : if (simd_support & JSIMD_3DNOW)
761 0 : return 1;
762 :
763 0 : return 0;
764 : }
765 :
766 : GLOBAL(void)
767 396 : jsimd_fdct_islow (DCTELEM * data)
768 : {
769 396 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
770 396 : jsimd_fdct_islow_sse2(data);
771 0 : else if (simd_support & JSIMD_MMX)
772 0 : jsimd_fdct_islow_mmx(data);
773 396 : }
774 :
775 : GLOBAL(void)
776 0 : jsimd_fdct_ifast (DCTELEM * data)
777 : {
778 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_fdct_islow_sse2))
779 0 : jsimd_fdct_ifast_sse2(data);
780 0 : else if (simd_support & JSIMD_MMX)
781 0 : jsimd_fdct_ifast_mmx(data);
782 0 : }
783 :
784 : GLOBAL(void)
785 0 : jsimd_fdct_float (FAST_FLOAT * data)
786 : {
787 0 : if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_fdct_float_sse))
788 0 : jsimd_fdct_float_sse(data);
789 0 : else if (simd_support & JSIMD_3DNOW)
790 0 : jsimd_fdct_float_3dnow(data);
791 0 : }
792 :
793 : GLOBAL(int)
794 3 : jsimd_can_quantize (void)
795 : {
796 3 : init_simd();
797 :
798 : /* The code is optimised for these values only */
799 : if (DCTSIZE != 8)
800 : return 0;
801 : if (sizeof(JCOEF) != 2)
802 : return 0;
803 : if (sizeof(DCTELEM) != 2)
804 : return 0;
805 :
806 3 : if (simd_support & JSIMD_SSE2)
807 3 : return 1;
808 0 : if (simd_support & JSIMD_MMX)
809 0 : return 1;
810 :
811 0 : return 0;
812 : }
813 :
814 : GLOBAL(int)
815 0 : jsimd_can_quantize_float (void)
816 : {
817 0 : init_simd();
818 :
819 : /* The code is optimised for these values only */
820 : if (DCTSIZE != 8)
821 : return 0;
822 : if (sizeof(JCOEF) != 2)
823 : return 0;
824 : if (sizeof(FAST_FLOAT) != 4)
825 : return 0;
826 :
827 0 : if (simd_support & JSIMD_SSE2)
828 0 : return 1;
829 0 : if (simd_support & JSIMD_SSE)
830 0 : return 1;
831 0 : if (simd_support & JSIMD_3DNOW)
832 0 : return 1;
833 :
834 0 : return 0;
835 : }
836 :
837 : GLOBAL(void)
838 396 : jsimd_quantize (JCOEFPTR coef_block, DCTELEM * divisors,
839 : DCTELEM * workspace)
840 : {
841 396 : if (simd_support & JSIMD_SSE2)
842 396 : jsimd_quantize_sse2(coef_block, divisors, workspace);
843 0 : else if (simd_support & JSIMD_MMX)
844 0 : jsimd_quantize_mmx(coef_block, divisors, workspace);
845 396 : }
846 :
847 : GLOBAL(void)
848 0 : jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors,
849 : FAST_FLOAT * workspace)
850 : {
851 0 : if (simd_support & JSIMD_SSE2)
852 0 : jsimd_quantize_float_sse2(coef_block, divisors, workspace);
853 0 : else if (simd_support & JSIMD_SSE)
854 0 : jsimd_quantize_float_sse(coef_block, divisors, workspace);
855 0 : else if (simd_support & JSIMD_3DNOW)
856 0 : jsimd_quantize_float_3dnow(coef_block, divisors, workspace);
857 0 : }
858 :
859 : GLOBAL(int)
860 0 : jsimd_can_idct_2x2 (void)
861 : {
862 0 : init_simd();
863 :
864 : /* The code is optimised for these values only */
865 : if (DCTSIZE != 8)
866 : return 0;
867 : if (sizeof(JCOEF) != 2)
868 : return 0;
869 : if (BITS_IN_JSAMPLE != 8)
870 : return 0;
871 : if (sizeof(JDIMENSION) != 4)
872 : return 0;
873 : if (sizeof(ISLOW_MULT_TYPE) != 2)
874 : return 0;
875 :
876 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
877 0 : return 1;
878 0 : if (simd_support & JSIMD_MMX)
879 0 : return 1;
880 :
881 0 : return 0;
882 : }
883 :
884 : GLOBAL(int)
885 0 : jsimd_can_idct_4x4 (void)
886 : {
887 0 : init_simd();
888 :
889 : /* The code is optimised for these values only */
890 : if (DCTSIZE != 8)
891 : return 0;
892 : if (sizeof(JCOEF) != 2)
893 : return 0;
894 : if (BITS_IN_JSAMPLE != 8)
895 : return 0;
896 : if (sizeof(JDIMENSION) != 4)
897 : return 0;
898 : if (sizeof(ISLOW_MULT_TYPE) != 2)
899 : return 0;
900 :
901 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
902 0 : return 1;
903 0 : if (simd_support & JSIMD_MMX)
904 0 : return 1;
905 :
906 0 : return 0;
907 : }
908 :
909 : GLOBAL(void)
910 0 : jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
911 : JCOEFPTR coef_block, JSAMPARRAY output_buf,
912 : JDIMENSION output_col)
913 : {
914 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
915 0 : jsimd_idct_2x2_sse2(compptr->dct_table, coef_block, output_buf, output_col);
916 0 : else if (simd_support & JSIMD_MMX)
917 0 : jsimd_idct_2x2_mmx(compptr->dct_table, coef_block, output_buf, output_col);
918 0 : }
919 :
920 : GLOBAL(void)
921 0 : jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
922 : JCOEFPTR coef_block, JSAMPARRAY output_buf,
923 : JDIMENSION output_col)
924 : {
925 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_red_sse2))
926 0 : jsimd_idct_4x4_sse2(compptr->dct_table, coef_block, output_buf, output_col);
927 0 : else if (simd_support & JSIMD_MMX)
928 0 : jsimd_idct_4x4_mmx(compptr->dct_table, coef_block, output_buf, output_col);
929 0 : }
930 :
931 : GLOBAL(int)
932 15 : jsimd_can_idct_islow (void)
933 : {
934 15 : init_simd();
935 :
936 : /* The code is optimised for these values only */
937 : if (DCTSIZE != 8)
938 : return 0;
939 : if (sizeof(JCOEF) != 2)
940 : return 0;
941 : if (BITS_IN_JSAMPLE != 8)
942 : return 0;
943 : if (sizeof(JDIMENSION) != 4)
944 : return 0;
945 : if (sizeof(ISLOW_MULT_TYPE) != 2)
946 : return 0;
947 :
948 15 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_islow_sse2))
949 15 : return 1;
950 0 : if (simd_support & JSIMD_MMX)
951 0 : return 1;
952 :
953 0 : return 0;
954 : }
955 :
956 : GLOBAL(int)
957 0 : jsimd_can_idct_ifast (void)
958 : {
959 0 : init_simd();
960 :
961 : /* The code is optimised for these values only */
962 : if (DCTSIZE != 8)
963 : return 0;
964 : if (sizeof(JCOEF) != 2)
965 : return 0;
966 : if (BITS_IN_JSAMPLE != 8)
967 : return 0;
968 : if (sizeof(JDIMENSION) != 4)
969 : return 0;
970 : if (sizeof(IFAST_MULT_TYPE) != 2)
971 : return 0;
972 : if (IFAST_SCALE_BITS != 2)
973 : return 0;
974 :
975 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
976 0 : return 1;
977 0 : if (simd_support & JSIMD_MMX)
978 0 : return 1;
979 :
980 0 : return 0;
981 : }
982 :
983 : GLOBAL(int)
984 0 : jsimd_can_idct_float (void)
985 : {
986 0 : init_simd();
987 :
988 : if (DCTSIZE != 8)
989 : return 0;
990 : if (sizeof(JCOEF) != 2)
991 : return 0;
992 : if (BITS_IN_JSAMPLE != 8)
993 : return 0;
994 : if (sizeof(JDIMENSION) != 4)
995 : return 0;
996 : if (sizeof(FAST_FLOAT) != 4)
997 : return 0;
998 : if (sizeof(FLOAT_MULT_TYPE) != 4)
999 : return 0;
1000 :
1001 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_float_sse2))
1002 0 : return 1;
1003 0 : if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_idct_float_sse))
1004 0 : return 1;
1005 0 : if (simd_support & JSIMD_3DNOW)
1006 0 : return 1;
1007 :
1008 0 : return 0;
1009 : }
1010 :
1011 : GLOBAL(void)
1012 131 : jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
1013 : JCOEFPTR coef_block, JSAMPARRAY output_buf,
1014 : JDIMENSION output_col)
1015 : {
1016 131 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_islow_sse2))
1017 131 : jsimd_idct_islow_sse2(compptr->dct_table, coef_block, output_buf, output_col);
1018 0 : else if (simd_support & JSIMD_MMX)
1019 0 : jsimd_idct_islow_mmx(compptr->dct_table, coef_block, output_buf, output_col);
1020 131 : }
1021 :
1022 : GLOBAL(void)
1023 0 : jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
1024 : JCOEFPTR coef_block, JSAMPARRAY output_buf,
1025 : JDIMENSION output_col)
1026 : {
1027 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_ifast_sse2))
1028 0 : jsimd_idct_ifast_sse2(compptr->dct_table, coef_block, output_buf, output_col);
1029 0 : else if (simd_support & JSIMD_MMX)
1030 0 : jsimd_idct_ifast_mmx(compptr->dct_table, coef_block, output_buf, output_col);
1031 0 : }
1032 :
1033 : GLOBAL(void)
1034 0 : jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
1035 : JCOEFPTR coef_block, JSAMPARRAY output_buf,
1036 : JDIMENSION output_col)
1037 : {
1038 0 : if ((simd_support & JSIMD_SSE2) && IS_ALIGNED_SSE(jconst_idct_float_sse2))
1039 0 : jsimd_idct_float_sse2(compptr->dct_table, coef_block,
1040 : output_buf, output_col);
1041 0 : else if ((simd_support & JSIMD_SSE) && IS_ALIGNED_SSE(jconst_idct_float_sse))
1042 0 : jsimd_idct_float_sse(compptr->dct_table, coef_block,
1043 : output_buf, output_col);
1044 0 : else if (simd_support & JSIMD_3DNOW)
1045 0 : jsimd_idct_float_3dnow(compptr->dct_table, coef_block,
1046 : output_buf, output_col);
1047 0 : }
1048 :
|