📄 pixman-combine.c
字号:
#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <string.h>#include "pixman-private.h"/* * There are two ways of handling alpha -- either as a single unified value or * a separate value for each component, hence each macro must have two * versions. The unified alpha version has a 'U' at the end of the name, * the component version has a 'C'. Similarly, functions which deal with * this difference will have two versions using the same convention. *//* * Combine src and mask */FASTCALL voidpixman_fbCombineMaskU (uint32_t *src, const uint32_t *mask, int width){ int i; for (i = 0; i < width; ++i) { uint32_t a = *(mask + i) >> 24; uint32_t s = *(src + i); FbByteMul(s, a); *(src + i) = s; }}/* * All of the composing functions */FASTCALL static voidfbCombineClear (uint32_t *dest, const uint32_t *src, int width){ memset(dest, 0, width*sizeof(uint32_t));}FASTCALL static voidfbCombineSrcU (uint32_t *dest, const uint32_t *src, int width){ memcpy(dest, src, width*sizeof(uint32_t));}/* if the Src is opaque, call fbCombineSrcU */FASTCALL static voidfbCombineOverU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint32_t ia = Alpha(~s); FbByteMulAdd(d, ia, s); *(dest + i) = d; }}/* if the Dst is opaque, this is a noop */FASTCALL static voidfbCombineOverReverseU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint32_t ia = Alpha(~*(dest + i)); FbByteMulAdd(s, ia, d); *(dest + i) = s; }}/* if the Dst is opaque, call fbCombineSrcU */FASTCALL static voidfbCombineInU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t a = Alpha(*(dest + i)); FbByteMul(s, a); *(dest + i) = s; }}/* if the Src is opaque, this is a noop */FASTCALL static voidfbCombineInReverseU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t d = *(dest + i); uint32_t a = Alpha(*(src + i)); FbByteMul(d, a); *(dest + i) = d; }}/* if the Dst is opaque, call fbCombineClear */FASTCALL static voidfbCombineOutU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t a = Alpha(~*(dest + i)); FbByteMul(s, a); *(dest + i) = s; }}/* if the Src is opaque, call fbCombineClear */FASTCALL static voidfbCombineOutReverseU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t d = *(dest + i); uint32_t a = Alpha(~*(src + i)); FbByteMul(d, a); *(dest + i) = d; }}/* if the Src is opaque, call fbCombineInU *//* if the Dst is opaque, call fbCombineOverU *//* if both the Src and Dst are opaque, call fbCombineSrcU */FASTCALL static voidfbCombineAtopU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint32_t dest_a = Alpha(d); uint32_t src_ia = Alpha(~s); FbByteAddMul(s, dest_a, d, src_ia); *(dest + i) = s; }}/* if the Src is opaque, call fbCombineOverReverseU *//* if the Dst is opaque, call fbCombineInReverseU *//* if both the Src and Dst are opaque, call fbCombineDstU */FASTCALL static voidfbCombineAtopReverseU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint32_t src_a = Alpha(s); uint32_t dest_ia = Alpha(~d); FbByteAddMul(s, dest_ia, d, src_a); *(dest + i) = s; }}/* if the Src is opaque, call fbCombineOverU *//* if the Dst is opaque, call fbCombineOverReverseU *//* if both the Src and Dst are opaque, call fbCombineClear */FASTCALL static voidfbCombineXorU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint32_t src_ia = Alpha(~s); uint32_t dest_ia = Alpha(~d); FbByteAddMul(s, dest_ia, d, src_ia); *(dest + i) = s; }}FASTCALL static voidfbCombineAddU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); FbByteAdd(d, s); *(dest + i) = d; }}/* if the Src is opaque, call fbCombineAddU *//* if the Dst is opaque, call fbCombineAddU *//* if both the Src and Dst are opaque, call fbCombineAddU */FASTCALL static voidfbCombineSaturateU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint16_t sa, da; sa = s >> 24; da = ~d >> 24; if (sa > da) { sa = FbIntDiv(da, sa); FbByteMul(s, sa); }; FbByteAdd(d, s); *(dest + i) = d; }}/* * All of the disjoint composing functions The four entries in the first column indicate what source contributions come from each of the four areas of the picture -- areas covered by neither A nor B, areas covered only by A, areas covered only by B and finally areas covered by both A and B. Disjoint Conjoint Fa Fb Fa Fb (0,0,0,0) 0 0 0 0 (0,A,0,A) 1 0 1 0 (0,0,B,B) 0 1 0 1 (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0) (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1 (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0 (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1) (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0 (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0) (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0) (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b) (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)*/#define CombineAOut 1#define CombineAIn 2#define CombineBOut 4#define CombineBIn 8#define CombineClear 0#define CombineA (CombineAOut|CombineAIn)#define CombineB (CombineBOut|CombineBIn)#define CombineAOver (CombineAOut|CombineBOut|CombineAIn)#define CombineBOver (CombineAOut|CombineBOut|CombineBIn)#define CombineAAtop (CombineBOut|CombineAIn)#define CombineBAtop (CombineAOut|CombineBIn)#define CombineXor (CombineAOut|CombineBOut)/* portion covered by a but not b */FASTCALL static uint8_tfbCombineDisjointOutPart (uint8_t a, uint8_t b){ /* min (1, (1-b) / a) */ b = ~b; /* 1 - b */ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ return 0xff; /* 1 */ return FbIntDiv(b,a); /* (1-b) / a */}/* portion covered by both a and b */FASTCALL static uint8_tfbCombineDisjointInPart (uint8_t a, uint8_t b){ /* max (1-(1-b)/a,0) */ /* = - min ((1-b)/a - 1, 0) */ /* = 1 - min (1, (1-b)/a) */ b = ~b; /* 1 - b */ if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ return 0; /* 1 - 1 */ return ~FbIntDiv(b,a); /* 1 - (1-b) / a */}/* portion covered by a but not b */FASTCALL static uint8_tfbCombineConjointOutPart (uint8_t a, uint8_t b){ /* max (1-b/a,0) */ /* = 1-min(b/a,1) */ /* min (1, (1-b) / a) */ if (b >= a) /* b >= a -> b/a >= 1 */ return 0x00; /* 0 */ return ~FbIntDiv(b,a); /* 1 - b/a */}/* portion covered by both a and b */FASTCALL static uint8_tfbCombineConjointInPart (uint8_t a, uint8_t b){ /* min (1,b/a) */ if (b >= a) /* b >= a -> b/a >= 1 */ return 0xff; /* 1 */ return FbIntDiv(b,a); /* b/a */}FASTCALL static voidfbCombineDisjointGeneralU (uint32_t *dest, const uint32_t *src, int width, uint8_t combine){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint32_t d = *(dest + i); uint32_t m,n,o,p; uint16_t Fa, Fb, t, u, v; uint8_t sa = s >> 24; uint8_t da = d >> 24; switch (combine & CombineA) { default: Fa = 0; break; case CombineAOut: Fa = fbCombineDisjointOutPart (sa, da); break; case CombineAIn: Fa = fbCombineDisjointInPart (sa, da); break; case CombineA: Fa = 0xff; break; } switch (combine & CombineB) { default: Fb = 0; break; case CombineBOut: Fb = fbCombineDisjointOutPart (da, sa); break; case CombineBIn: Fb = fbCombineDisjointInPart (da, sa); break; case CombineB: Fb = 0xff; break; } m = FbGen (s,d,0,Fa,Fb,t, u, v); n = FbGen (s,d,8,Fa,Fb,t, u, v); o = FbGen (s,d,16,Fa,Fb,t, u, v); p = FbGen (s,d,24,Fa,Fb,t, u, v); s = m|n|o|p; *(dest + i) = s; }}FASTCALL static voidfbCombineDisjointOverU (uint32_t *dest, const uint32_t *src, int width){ int i; for (i = 0; i < width; ++i) { uint32_t s = *(src + i); uint16_t a = s >> 24; if (a != 0x00) { if (a != 0xff) { uint32_t d = *(dest + i); a = fbCombineDisjointOutPart (d >> 24, a); FbByteMulAdd(d, a, s); s = d; } *(dest + i) = s; } }}FASTCALL static voidfbCombineDisjointInU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineAIn);}FASTCALL static voidfbCombineDisjointInReverseU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineBIn);}FASTCALL static voidfbCombineDisjointOutU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineAOut);}FASTCALL static voidfbCombineDisjointOutReverseU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineBOut);}FASTCALL static voidfbCombineDisjointAtopU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineAAtop);}FASTCALL static voidfbCombineDisjointAtopReverseU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineBAtop);}FASTCALL static voidfbCombineDisjointXorU (uint32_t *dest, const uint32_t *src, int width){ fbCombineDisjointGeneralU (dest, src, width, CombineXor);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -