一个快速的8级Alpha混合算法优化的边界只局限于你的知识好像学习吧

42次阅读

共计 2320 个字符,预计需要花费 6 分钟才能阅读完成。

当我以为自己的程序已经写的足够好了,一个博士随便写了一个 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

正文完
 0