darling-cocotron/Onyx2D/O2argb8u.h
2010-10-22 11:57:22 -04:00

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);