First public contribution.
3 * Eric Anholt. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
31 #include <liboil/liboilclasses.h>
32 #include <liboil/liboilfunction.h>
33 #include "liboil/liboilcolorspace.h"
35 #define COMPOSITE_ADD(d,s) oil_clamp_255((d) + (s))
36 #define COMPOSITE_OVER(d,s,m) ((d) + (s) - oil_muldiv_255((d),(m)))
39 composite_in_argb_fast (uint32_t *dest, const uint32_t *src,
40 const uint8_t *mask, int n)
46 /* Split the pixel into two sets of two channels, and multiply by the
49 src1 = *src & 0x00ff00ff;
52 src1 += (src1 >> 8) & 0x00ff00ff;
56 src2 = (*src >> 8) & 0x00ff00ff;
59 src2 += (src2 >> 8) & 0x00ff00ff;
62 *dest++ = src1 | src2;
66 OIL_DEFINE_IMPL (composite_in_argb_fast, composite_in_argb);
69 composite_in_argb_const_src_fast (uint32_t *dest, const uint32_t *src,
70 const uint8_t *mask, int n)
74 src1 = *src & 0x00ff00ff;
75 src2 = (*src >> 8) & 0x00ff00ff;
78 uint32_t temp1, temp2;
81 /* Split the pixel into two sets of two channels, and multiply by the
86 temp1 += (temp1 >> 8) & 0x00ff00ff;
92 temp2 += (temp2 >> 8) & 0x00ff00ff;
95 *dest++ = temp1 | temp2;
98 OIL_DEFINE_IMPL (composite_in_argb_const_src_fast, composite_in_argb_const_src);
101 composite_in_argb_const_mask_fast (uint32_t *dest, const uint32_t *src,
102 const uint8_t *mask, int n)
109 /* Split the pixel into two sets of two channels, and multiply by the
112 src1 = *src & 0x00ff00ff;
115 src1 += (src1 >> 8) & 0x00ff00ff;
119 src2 = (*src >> 8) & 0x00ff00ff;
122 src2 += (src2 >> 8) & 0x00ff00ff;
125 *dest++ = src1 | src2;
129 OIL_DEFINE_IMPL (composite_in_argb_const_mask_fast,
130 composite_in_argb_const_mask);
133 composite_over_argb_fast (uint32_t *dest, const uint32_t *src, int n)
136 uint32_t d = *dest, s = *src, sa;
137 uint32_t s1, s2, d1, d2;
145 d1 += (d1 >> 8) & 0x00ff00ff;
149 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
152 s2 = (s >> 8) & 0x00ff00ff;
153 d2 = (d >> 8) & 0x00ff00ff;
156 d2 += (d2 >> 8) & 0x00ff00ff;
160 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
163 *dest++ = d1 | (d2 << 8);
167 OIL_DEFINE_IMPL (composite_over_argb_fast, composite_over_argb);
170 composite_over_argb_const_src_fast (uint32_t *dest, const uint32_t *src, int n)
177 s2 = (s >> 8) & 0x00ff00ff;
186 d1 += (d1 >> 8) & 0x00ff00ff;
190 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
193 d2 = (d >> 8) & 0x00ff00ff;
196 d2 += (d2 >> 8) & 0x00ff00ff;
200 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
203 *dest++ = d1 | (d2 << 8);
207 OIL_DEFINE_IMPL (composite_over_argb_const_src_fast,
208 composite_over_argb_const_src);
211 composite_add_argb_fast (uint32_t *dest, const uint32_t *src, int n)
214 uint32_t s = *src++, d = *dest;
215 uint32_t s1, s2, d1, d2;
218 s2 = (s >> 8) & 0x00ff00ff;
220 d2 = (d >> 8) & 0x00ff00ff;
223 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
227 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
230 *dest++ = d1 | (d2 << 8);
233 OIL_DEFINE_IMPL (composite_add_argb_fast, composite_add_argb);
236 composite_add_argb_const_src_fast (uint32_t *dest, const uint32_t *src, int n)
240 s1 = *src & 0x00ff00ff;
241 s2 = (*src >> 8) & 0x00ff00ff;
247 d2 = (d >> 8) & 0x00ff00ff;
250 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
254 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
257 *dest++ = d1 | (d2 << 8);
260 OIL_DEFINE_IMPL (composite_add_argb_const_src_fast,
261 composite_add_argb_const_src);
264 composite_in_over_argb_fast (uint32_t *dest, const uint32_t *src,
265 const uint8_t *mask, int n)
268 uint32_t d = *dest, s = *src++;
269 uint32_t s1, s2, d1, d2, sa;
273 s2 = (s >> 8) & 0x00ff00ff;
278 s1 += (s1 >> 8) & 0x00ff00ff;
284 s2 += (s2 >> 8) & 0x00ff00ff;
289 sa = (~s2 >> 16) & 0xff;
294 d1 += (d1 >> 8) & 0x00ff00ff;
298 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
301 d2 = (d >> 8) & 0x00ff00ff;
304 d2 += (d2 >> 8) & 0x00ff00ff;
308 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
311 *dest++ = d1 | (d2 << 8);
314 OIL_DEFINE_IMPL (composite_in_over_argb_fast, composite_in_over_argb);
317 composite_in_over_argb_const_src_fast (uint32_t *dest, const uint32_t *src,
318 const uint8_t *mask, int n)
324 s2 = (s >> 8) & 0x00ff00ff;
328 uint32_t temp1, temp2, d1, d2, sa;
334 temp1 += (temp1 >> 8) & 0x00ff00ff;
340 temp2 += (temp2 >> 8) & 0x00ff00ff;
345 sa = (~temp2 >> 16) & 0xff;
350 d1 += (d1 >> 8) & 0x00ff00ff;
354 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
357 d2 = (d >> 8) & 0x00ff00ff;
360 d2 += (d2 >> 8) & 0x00ff00ff;
364 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
367 *dest++ = d1 | (d2 << 8);
370 OIL_DEFINE_IMPL (composite_in_over_argb_const_src_fast,
371 composite_in_over_argb_const_src);
374 composite_in_over_argb_const_mask_fast (uint32_t *dest, const uint32_t *src,
375 const uint8_t *mask, int n)
379 uint32_t d = *dest, s = *src++;
380 uint32_t s1, s2, d1, d2, sa;
383 s2 = (s >> 8) & 0x00ff00ff;
388 s1 += (s1 >> 8) & 0x00ff00ff;
394 s2 += (s2 >> 8) & 0x00ff00ff;
399 sa = (~s2 >> 16) & 0xff;
404 d1 += (d1 >> 8) & 0x00ff00ff;
408 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
411 d2 = (d >> 8) & 0x00ff00ff;
414 d2 += (d2 >> 8) & 0x00ff00ff;
418 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
421 *dest++ = d1 | (d2 << 8);
424 OIL_DEFINE_IMPL (composite_in_over_argb_const_mask_fast,
425 composite_in_over_argb_const_mask);
427 #ifdef HAVE_UNALIGNED_ACCESS
429 composite_add_u8_fast (uint8_t *dest, const uint8_t *src, int n)
431 for (; n > 3; n-= 4) {
432 uint32_t s = *(uint32_t *)src, d = *(uint32_t *)dest;
433 uint32_t s1, s2, d1, d2;
436 s2 = (s >> 8) & 0x00ff00ff;
438 d2 = (d >> 8) & 0x00ff00ff;
441 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
445 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
448 *(uint32_t *)dest = d1 | (d2 << 8);
453 *dest = COMPOSITE_ADD(*dest, *src);
458 OIL_DEFINE_IMPL (composite_add_u8_fast, composite_add_u8);
461 #ifdef HAVE_UNALIGNED_ACCESS
463 composite_add_u8_const_src_fast (uint8_t *dest, const uint8_t *src, int n)
467 s = *src | (*src << 16);
468 for (; n > 3; n-= 4) {
469 uint32_t d = *(uint32_t *)dest;
473 d2 = (d >> 8) & 0x00ff00ff;
476 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
480 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
483 *(uint32_t *)dest = d1 | (d2 << 8);
487 *dest = COMPOSITE_ADD(*dest, *src);
491 OIL_DEFINE_IMPL (composite_add_u8_const_src_fast, composite_add_u8_const_src);
494 #ifdef HAVE_UNALIGNED_ACCESS
496 composite_over_u8_fast (uint8_t *dest, const uint8_t *src, int n)
498 for (; n > 3; n-= 4) {
499 uint32_t d = *(uint32_t *)dest, s = *(uint32_t *)src;
500 uint32_t d1, d2, s1, s2;
503 d2 = (d >> 8) & 0x00ff00ff;
505 s2 = (s >> 8) & 0x00ff00ff;
507 d1 = ((d1 & 0xff) * (~s1 & 0xff)) |
508 ((d1 & 0x00ff0000) * (~s1 >> 16 & 0xff));
510 d1 += (d1 >> 8) & 0x00ff00ff;
514 d1 |= 0x01000100 - ((d1 >> 8) & 0x00ff00ff);
517 d2 = ((d2 & 0xff) * (~s2 & 0xff)) |
518 ((d2 & 0x00ff0000) * (~s2 >> 16 & 0xff));
520 d2 += (d2 >> 8) & 0x00ff00ff;
524 d2 |= 0x01000100 - ((d2 >> 8) & 0x00ff00ff);
527 *(uint32_t *)dest = d1 | (d2 << 8);
532 *dest = COMPOSITE_OVER(*dest, *src, *src);
537 OIL_DEFINE_IMPL (composite_over_u8_fast, composite_over_u8);
543 OilFunctionImpl* __oil_function_impl_composite_in_argb_fast() {
544 return &_oil_function_impl_composite_in_argb_fast;
550 OilFunctionImpl* __oil_function_impl_composite_in_argb_const_src_fast() {
551 return &_oil_function_impl_composite_in_argb_const_src_fast;
557 OilFunctionImpl* __oil_function_impl_composite_in_argb_const_mask_fast() {
558 return &_oil_function_impl_composite_in_argb_const_mask_fast;
564 OilFunctionImpl* __oil_function_impl_composite_over_argb_fast() {
565 return &_oil_function_impl_composite_over_argb_fast;
571 OilFunctionImpl* __oil_function_impl_composite_over_argb_const_src_fast() {
572 return &_oil_function_impl_composite_over_argb_const_src_fast;
578 OilFunctionImpl* __oil_function_impl_composite_add_argb_fast() {
579 return &_oil_function_impl_composite_add_argb_fast;
585 OilFunctionImpl* __oil_function_impl_composite_add_argb_const_src_fast() {
586 return &_oil_function_impl_composite_add_argb_const_src_fast;
592 OilFunctionImpl* __oil_function_impl_composite_in_over_argb_fast() {
593 return &_oil_function_impl_composite_in_over_argb_fast;
599 OilFunctionImpl* __oil_function_impl_composite_in_over_argb_const_src_fast() {
600 return &_oil_function_impl_composite_in_over_argb_const_src_fast;
606 OilFunctionImpl* __oil_function_impl_composite_in_over_argb_const_mask_fast() {
607 return &_oil_function_impl_composite_in_over_argb_const_mask_fast;
611 #ifdef HAVE_UNALIGNED_ACCESS
614 OilFunctionImpl* __oil_function_impl_composite_add_u8_fast() {
615 return &_oil_function_impl_composite_add_u8_fast;
620 #ifdef HAVE_UNALIGNED_ACCESS
623 OilFunctionImpl* __oil_function_impl_composite_add_u8_const_src_fast() {
624 return &_oil_function_impl_composite_add_u8_const_src_fast;
629 #ifdef HAVE_UNALIGNED_ACCESS
632 OilFunctionImpl* __oil_function_impl_composite_over_u8_fast() {
633 return &_oil_function_impl_composite_over_u8_fast;