mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-10-07 17:43:28 +00:00
153 lines
4.2 KiB
Objective-C
153 lines
4.2 KiB
Objective-C
#import <Foundation/NSObject.h>
|
|
#import <Onyx2D/O2Geometry.h>
|
|
#import <Onyx2D/VGmath.h>
|
|
|
|
typedef struct {
|
|
uint8_t a;
|
|
uint8_t r;
|
|
uint8_t g;
|
|
uint8_t b;
|
|
} O2argb8u_BE;
|
|
|
|
typedef struct {
|
|
uint8_t b;
|
|
uint8_t g;
|
|
uint8_t r;
|
|
uint8_t a;
|
|
} O2argb8u_LE;
|
|
|
|
typedef struct {
|
|
uint8_t r;
|
|
uint8_t g;
|
|
uint8_t b;
|
|
uint8_t a;
|
|
} O2rgba8u_BE;
|
|
|
|
#ifdef __LITTLE_ENDIAN__
|
|
typedef O2argb8u_LE O2argb8u;
|
|
#endif
|
|
#ifdef __BIG_ENDIAN__
|
|
typedef O2argb8u_BE O2argb8u;
|
|
#endif
|
|
|
|
#define COVERAGE_MULTIPLIER 256
|
|
|
|
static inline uint32_t inverseCoverage(uint32_t coverage){
|
|
return COVERAGE_MULTIPLIER-coverage;
|
|
}
|
|
|
|
static inline uint32_t multiplyByCoverage(uint32_t value,uint32_t coverage){
|
|
return (value*coverage)/COVERAGE_MULTIPLIER;
|
|
}
|
|
|
|
|
|
static inline uint32_t O2Image_16u_div_255(uint32_t t){
|
|
// t/255
|
|
// From Imaging Compositing Fundamentals, Technical Memo 4 by Alvy Ray Smith, Aug 15, 1995
|
|
// Faster and more accurate in that it rounds instead of truncates
|
|
// Perfectly accurate for 8 and 16 bit values
|
|
// (loses a small amount of precision for >16 bits values)
|
|
t = t + 0x80;
|
|
t= ( ( ( (t)>>8 ) + (t) )>>8 );
|
|
|
|
return t;
|
|
}
|
|
|
|
static inline uint8_t O2Image_8u_mul_8u_div_255(uint8_t c,uint8_t a){
|
|
return O2Image_16u_div_255(c*a);
|
|
}
|
|
|
|
static inline uint16_t O2Image_16u_mul_8u_div_255(uint16_t c,uint8_t a){
|
|
return O2Image_16u_div_255(c*a);
|
|
}
|
|
|
|
ONYX2D_STATIC_INLINE uint32_t Mul8x2(uint32_t pair,uint32_t alpha){
|
|
const uint32_t rbmask=0x00FF00FF;
|
|
pair &= rbmask;
|
|
uint32_t i = alpha * pair + 0x800080;
|
|
return (i + ((i >> 8) & rbmask)) >> 8 & rbmask;
|
|
}
|
|
|
|
static inline O2argb8u O2argb8uMultiplyByMask8u(O2argb8u result,uint32_t value){
|
|
result.r=O2Image_8u_mul_8u_div_255(result.r,value);
|
|
result.g=O2Image_8u_mul_8u_div_255(result.g,value);
|
|
result.b=O2Image_8u_mul_8u_div_255(result.b,value);
|
|
result.a=O2Image_8u_mul_8u_div_255(result.a,value);
|
|
|
|
return result;
|
|
}
|
|
|
|
static inline O2argb8u O2argb8uMultiplyByCoverageNoBypass(O2argb8u result,unsigned value){
|
|
result.r=multiplyByCoverage(result.r,value);
|
|
result.g=multiplyByCoverage(result.g,value);
|
|
result.b=multiplyByCoverage(result.b,value);
|
|
result.a=multiplyByCoverage(result.a,value);
|
|
|
|
return result;
|
|
}
|
|
|
|
static inline O2argb8u O2argb8uMultiplyByCoverage(O2argb8u result,unsigned value){
|
|
if(value!=COVERAGE_MULTIPLIER)
|
|
result=O2argb8uMultiplyByCoverageNoBypass(result,value);
|
|
|
|
return result;
|
|
}
|
|
|
|
static inline O2argb8u O2argb8uMultiplyByCoverageAdd(O2argb8u left,uint32_t leftCoverage,O2argb8u right,uint32_t rightCoverage){
|
|
uint32_t srb=*(uint32_t *)&left;
|
|
uint32_t sag=srb>>8;
|
|
|
|
sag&=0x00FF00FF;
|
|
srb&=0x00FF00FF;
|
|
sag=((sag*leftCoverage)>>8)&0x00FF00FF;
|
|
srb=((srb*leftCoverage)>>8)&0x00FF00FF;
|
|
|
|
uint32_t drb=*(uint32_t *)&right;
|
|
uint32_t dag=drb>>8;
|
|
|
|
dag&=0x00FF00FF;
|
|
drb&=0x00FF00FF;
|
|
|
|
dag=((dag*rightCoverage)>>8)&0x00FF00FF;
|
|
drb=((drb*rightCoverage)>>8)&0x00FF00FF;
|
|
|
|
uint32_t r;
|
|
|
|
sag+=dag;
|
|
r=RI_INT_MIN(sag,0x00FF0000)<<8;
|
|
r|=RI_INT_MIN(sag&0xFFFF,255)<<8;
|
|
srb+=drb;
|
|
r|=RI_INT_MIN(srb,0x00FF0000);
|
|
r|=RI_INT_MIN(srb&0xFFFF,255);
|
|
|
|
return *(O2argb8u *)&r;
|
|
}
|
|
|
|
static inline O2argb8u O2argb8uAdd(O2argb8u result,O2argb8u other){
|
|
result.r=RI_INT_MIN((unsigned)result.r+(unsigned)other.r,255);
|
|
result.g=RI_INT_MIN((unsigned)result.g+(unsigned)other.g,255);
|
|
result.b=RI_INT_MIN((unsigned)result.b+(unsigned)other.b,255);
|
|
result.a=RI_INT_MIN((unsigned)result.a+(unsigned)other.a,255);
|
|
return result;
|
|
}
|
|
|
|
|
|
void O2ApplyCoverageAndMaskToSpan_largb8u_PRE(O2argb8u *dst,uint32_t icoverage,uint8_t *mask,O2argb8u *src,int length);
|
|
|
|
void O2ApplyCoverageToSpan_largb8u_PRE(O2argb8u *dst,int coverage,O2argb8u *src,int length);
|
|
|
|
|
|
void O2argb8u_sover_by_coverage(O2argb8u *src,O2argb8u *dst,unsigned coverage,int length);
|
|
|
|
void O2argb8u_copy_by_coverage(O2argb8u *src,O2argb8u *dst,unsigned coverage,int length);
|
|
|
|
void O2BlendSpanNormal_8888(O2argb8u *src,O2argb8u *dst,int length);
|
|
|
|
void O2BlendSpanClear_8888(O2argb8u *src,O2argb8u *dst,int length);
|
|
|
|
void O2BlendSpanCopy_8888(O2argb8u *src,O2argb8u *dst,int length);
|
|
|
|
void O2BlendSpanSourceIn_8888(O2argb8u *src,O2argb8u *dst,int length);
|
|
void O2BlendSpanXOR_8888(O2argb8u *src,O2argb8u *dst,int length);
|
|
void O2BlendSpanPlusLighter_8888(O2argb8u *src,O2argb8u *dst,int length);
|