static void doAlphaBlend(CDC *dst, int x, int y, int w, int h, CDC *src, int srcx, int srcy, CBitmap *mskBmp) { BLENDFUNCTION bf; CDC blendDC, mergeDC, maskDC; CBitmap *oldBlendBmp, *oldMergeBmp, *oldMaskBmp; CBitmap blendBmp, mergeBmp; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = CMainWnd::blendLevel; bf.AlphaFormat = 0; blendBmp.CreateCompatibleBitmap(dst, w, h); blendDC.CreateCompatibleDC(dst); oldBlendBmp = blendDC.SelectObject(&blendBmp); mergeBmp.CreateCompatibleBitmap(dst, w, h); mergeDC.CreateCompatibleDC(dst); oldMergeBmp = mergeDC.SelectObject(&mergeBmp); maskDC.CreateCompatibleDC(dst); oldMaskBmp = maskDC.SelectObject(mskBmp); blendDC.BitBlt(0, 0, w, h, dst, x, y, SRCCOPY); alphablend(blendDC, 0, 0, w, h, *src, srcx, srcy, w, h, bf); /* now blendDC has a alpha blended version of the penguin, unfortunatly the background has also been alpha blended and needs to be masked out */ mergeDC.BitBlt(0, 0, w, h, &maskDC, srcx, srcy, NOTSRCCOPY); mergeDC.BitBlt(0, 0, w, h, &blendDC, 0, 0, SRCAND); if (NULL == transparentblt) { dst->BitBlt(x, y, w, h, &maskDC, srcx, srcy, SRCAND); dst->BitBlt(x, y, w, h, &mergeDC, 0, 0, SRCPAINT); } else { transparentblt(*dst, x, y, w, h, mergeDC, 0, 0, w, h, BG_COLOUR); } maskDC.SelectObject(oldMaskBmp); mergeDC.SelectObject(oldMergeBmp); blendDC.SelectObject(oldBlendBmp); }
int blend_images(unsigned char *from, int from_w, int from_h, int from_depth, unsigned char *to, int to_w, int to_h, int to_depth, int off_x, int off_y, unsigned char alpha) { int a, b, from_size, to_size, sub_pixel; unsigned char *from_pix, *to_pix; if (to_depth != from_depth) { // unmatched depths return -1; } if (from_w > to_w || from_h > to_h) { // "from" image is bigger than "to" return -2; } if (((off_x + from_w) > to_w) || ((off_y + from_h) > to_h)) { // offset out of range return -3; } from_size=from_w*from_h* from_depth; to_size=to_w*to_h* to_depth; for (a=0; a<from_h; a++) { //height for (b=0; b<from_w * from_depth; b+=from_depth) { // width for (sub_pixel=0; sub_pixel < to_depth; sub_pixel++) { from_pix= from + (a * from_w * from_depth) + b + sub_pixel; to_pix= to + ((a+off_y) * to_w * to_depth) + (b + off_x)+ sub_pixel ; //to_pix= to + b + sub_pixel + (a * to_w * to_depth) ; *(to_pix)=alphablend(*(from_pix), *(to_pix), alpha); } } } }
DWORD LandScape::execV( LS_OPCODE _opcode, va_list _va ) { // reset the return status - individual functions will alter this if need be mExecStatus = EXEC_SUCCESS; mExecString[0] = '\0'; switch( _opcode ) { case LS_SEED: setSeed( va_arg(_va,DWORD) ); break; case LS_LOAD: return load( va_arg(_va,char*) ); case LS_LOADM: { char * tmpCh = va_arg(_va,char*); double tmpD = va_arg(_va,double); return load(tmpCh, float(tmpD)); } case LS_SAVE: return save( va_arg(_va,char*) ); case LS_CLEAR: clear(); break; case LS_PUSH: push( va_arg(_va,int)); break; case LS_POP: pop(); break; case LS_GET: return (DWORD)get( va_arg(_va,int) ); case LS_SWAP: swap(); break; case LS_DUP: dup(); break; case LS_ADD: add( float(va_arg(_va,double)) ); break; case LS_SUB: sub( float(va_arg(_va,double)) ); break; case LS_MUL: mul( float(va_arg(_va,double)) ); break; case LS_DIV: div( float(va_arg(_va,double)) ); break; case LS_EXP: exp( float(va_arg(_va,double)) ); break; case LS_NEG: neg(); break; case LS_CLR: clr( float(va_arg(_va,double)) ); break; case LS_DIFF: diff(); break; case LS_NORMALIZE: { double i = va_arg(_va,double); double j = va_arg(_va,double); normalize( float(i), float(j) ); } break; case LS_ADDS: addStack(); break; case LS_SUBS: subStack(); break; case LS_FLOOR: { double i = va_arg(_va,double); double j = va_arg(_va,double); double k = va_arg(_va,double); floor( float(i), float(j), float(k) ); } break; case LS_CEIL: { double i = va_arg(_va,double); double j = va_arg(_va,double); double k = va_arg(_va,double); ceil( i, j, k ); } break; case LS_CLIPMIN: clipMin( float(va_arg(_va,double)) ); break; case LS_CLIPMAX: clipMax( float(va_arg(_va,double)) ); break; case LS_ROT: rot(); break; case LS_FLIPX: flipX(); break; case LS_FLIPY: flipY(); break; case LS_TERRAIN: { int i = va_arg(_va,int); double j = va_arg(_va,double); if (i > 256) { terrain( 256, float(j) ); size(i); } else terrain( i, float(j) ); } break; case LS_PLASMA: { int i = va_arg(_va,int); double j = va_arg(_va,double); if (i > 256) { plasma( 256, float(j) ); size(i); } else plasma( i, float(j) ); } break; case LS_SIZE: size( va_arg(_va,int) ); break; case LS_SLOPE: { double i = va_arg(_va,double); int j = va_arg(_va,int); slope( i, float(j) ); } break; case LS_SHAVE: { double i = va_arg(_va,double); double j = va_arg(_va,double); double k = va_arg(_va,double); shaveArea( float(i), float(j), float(k) ); } break; case LS_CURVE: { double i = va_arg(_va,double); int j = va_arg(_va,int); curve( float(i), j ); } break; case LS_FFT: if (stack.size() > 1) fft( va_arg(_va,int) ); break; case LS_FILL_N: if (stack.size() > 1) fillNormal( float(va_arg(_va,double)) ); break; case LS_OVERLAY: { int i = va_arg(_va,int); double j = va_arg(_va,double); overlay( i, float(j) ); } break; case LS_ALPHABLEND: { int x = va_arg(_va, int); int y = va_arg(_va, int); alphablend(x, y); } break; case LS_BLEND: { int i = va_arg(_va,int); int j = va_arg(_va,int); blend( i, j ); } case LS_SMOOTH: { double i = va_arg(_va,double); double j = va_arg(_va,double); smooth( float(i), float(j) ); } break; case LS_TILE: tile(); break; case LS_WRAP: wrap(); break; case LS_CLAMP: { int i = va_arg(_va,int); double j = va_arg(_va,double); clamp(i, float(j)); } break; case LS_MASK: { int i = va_arg(_va,int); double j = va_arg(_va,double); mask(i, float(j)); } break; case LS_CRATER: case LS_PEAK: case LS_RING: case LS_FILLBASIN: case LS_LPFILTER: case LS_HPFILTER: case LS_BPFILTER: case LS_BRFILTER: case LS_FFLP: case LS_FFHP: case LS_FFBP: case LS_FFBR: default: break; } return NULL; }
void P2D_FillRect(const rect_st *rec) { rect_st lrect; color_t *pDest, *pPixel, *pEnd; uint32_t doublePx, pxCnt, wDest; coord_t xMin, yMin, xMax, yMax, x, y; if(rec != NULL) { lrect = *rec; P2D_ClipFit(&lrect); pxCnt = P2D_GetPixelCnt(&lrect); if(pxCnt > 0) { pDest = GetSurfaceAddr(); wDest = GetWidth(); /** Opaque output **/ if(context.alpha == 255) { /** Special case: horizontal line **/ if(lrect.w == 1) { pPixel = &pDest[wDest * lrect.y + lrect.x]; while(pxCnt--) { *pPixel = context.colFront; pPixel += wDest; } } /** regular rectangle **/ else { /*converts to standart coordinates (makes loop execution faster)*/ P2D_RectToCoord(&lrect, &xMin, &yMin, &xMax, &yMax); xMax++; yMax++; /*combine 2 pixels on a 32 bits word; will fill 2 pixels in 1 cycle*/ doublePx = ((uint32_t)context.colFront) << 16 | context.colFront; for(y = yMin; y < yMax; y++) { pPixel = &pDest[wDest * y + xMin]; pEnd = &pDest[wDest * y + xMax]; /*if the first pixel is not aligned @4 but @2, put 1 pixel manually*/ if((uint32_t)pPixel & 0x02) { *pPixel = context.colFront; pPixel++; } /*once aligned, write 2 pixel each cycle*/ while(pPixel < pEnd - 1) { * ((uint32_t *) pPixel) = doublePx; pPixel += 2; } /*...maybe the last pixel wasn't aligned @4; put it manually*/ while(pPixel < pEnd) { *pPixel = context.colFront; pPixel++; } } } } /** Alpha output **/ else { P2D_RectToCoord(&lrect, &xMin, &yMin, &xMax, &yMax); for(y = yMin; y <= yMax; y++) { pPixel = &pDest[wDest * y + xMin]; for(x = xMin; x <= xMax; x++) { *pPixel = alphablend(context.colFront, *pPixel, context.alpha); pPixel++; } } } } } }