当我以为自己的程序已经写的足够好了,一个博士随便写了一个 8 级 ALPHA 混合的算法来打脸。时隔多年,余音不绝。
虽然只有 8 级,但比我用定点数写的实现任意级的要快许多倍。从这个示例可以看出算法的威力,也可以看出数学是多么重要。
优化的边界只局限于你的知识,你以为只是你以为根据你的知识和经验拼尽全力也只能这样了。
/// 获取 RGB 分量的掩码
#define RGB565_R_MASK 0xF800
#define RGB565_G_MASK 0x07E0
#define RGB565_B_MASK 0x001F
#define RGB565_R_LBIT 0x0800
#define RGB565_G_LBIT 0x0020
#define RGB565_B_LBIT 0x0001
#define RGB565_R_MBIT 0x8000
#define RGB565_G_MBIT 0x0400
#define RGB565_B_MBIT 0x0010
/// 混合了 RGB?位
#define RGB565_MSBIT (RGB565_R_MBIT | RGB565_G_MBIT | RGB565_B_MBIT)
#define RGB565_LSBIT (RGB565_R_LBIT | RGB565_G_LBIT | RGB565_B_LBIT)
#define RGB565_R_M2BIT (RGB565_R_MBIT | (RGB565_R_MBIT >> 1))
#define RGB565_G_M2BIT (RGB565_G_MBIT | (RGB565_G_MBIT >> 1))
#define RGB565_B_M2BIT (RGB565_B_MBIT | (RGB565_B_MBIT >> 1))
#define RGB565_R_M3BIT (RGB565_R_MBIT | (RGB565_R_MBIT >> 1) | (RGB565_R_MBIT >> 2))
#define RGB565_G_M3BIT (RGB565_G_MBIT | (RGB565_G_MBIT >> 1) | (RGB565_G_MBIT >> 2))
#define RGB565_B_M3BIT (RGB565_B_MBIT | (RGB565_B_MBIT >> 1) | (RGB565_B_MBIT >> 2))
// Image 为某种内存图像结构定义
void vBlendImage(unsigned int vAddr, Image* lpImage, unsigned int xSrc, unsigned int ySrc, unsigned int width, unsigned int height, unsigned int coef) {
unsigned int i,j,dwidth,dheight,deltawidth;
unsigned int* dp = (unsigned int *)vAddr;
unsigned int* dp1;
unsigned int* sp = lpImage->databuf;
if(xSrc >= SCREEN_WIDTH || ySrc >= SCREEN_HEIGHT){return;}
dwidth = lpImage->width;
dheight = lpImage->height;
deltawidth = dwidth - width;
/*
if(xSrc + width > SCREEN_WIDTH){width = SCREEN_WIDTH - xSrc;}
if(ySrc + height > SCREEN_HEIGHT){height = SCREEN_HEIGHT - ySrc;}
*/
dp += (ySrc * (DTMAXX + 1) + xSrc);
unsigned int scolor, dcolor;
unsigned int mcolor;
unsigned int skcolor, dkcolor;
unsigned int xcolor;
for(i=0; i<height; i++){
dp1 = dp;
for(j=0; j<width; j++){
scolor = *sp++;
xcolor = dcolor = *dp1;
skcolor = scolor & RGB565_LSBIT;
scolor = scolor & ~RGB565_LSBIT;
dkcolor = dcolor & RGB565_LSBIT;
dcolor = dcolor & ~RGB565_LSBIT;
if(coef & BIT0){
mcolor = xcolor & skcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + scolor;
xcolor = (xcolor >> 1) + mcolor;
}
if(coef & BIT1){
mcolor = xcolor & skcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + scolor;
xcolor = (xcolor >> 1) + mcolor;
}else{if(xcolor != dcolor){
mcolor = xcolor & dkcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + dcolor;
xcolor = (xcolor >> 1) + mcolor;
}
}
if(coef & BIT2){
mcolor = xcolor & skcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + scolor;
xcolor = (xcolor >> 1) + mcolor;
}else{if(xcolor != dcolor){
mcolor = xcolor & dkcolor;
xcolor = (xcolor & ~RGB565_LSBIT) + dcolor;
xcolor = (xcolor >> 1) + mcolor;
}
}
*dp1++ = xcolor;
}
sp += deltawidth;
dp += SCREE_WIDTH;
} // for
} // func