#include "camtypes.h"
#include "fthrconv.h"
#include "bshadow.h"
Go to the source code of this file.
Functions | |
UINT32 | FloorSqrt (const double D) |
LPBITMAPINFO | Shadow32BppBitmap (const UINT32 nBlur, LPBITMAPINFO pSrcInfo, LPBYTE pSrcBits32, LPBYTE *pDestBits) |
LPBITMAPINFO | Shadow8BppBitmap (const UINT32 nBlur, LPBITMAPINFO pSrcInfo, LPBYTE pSrcBits8, LPBYTE *pDestBits) |
Variables | |
const double | HalfX = 0.4999999999999 |
|
Definition at line 114 of file fthrconv.cpp. 00115 { 00116 #if defined(_M_IX86) 00117 UINT32 I ; 00118 __asm fld D 00119 __asm fsqrt 00120 __asm fsub HalfX 00121 __asm fistp I 00122 return I ; 00123 #else 00124 return (UINT32)sqrt(D) ; 00125 #endif 00126 }
|
|
/ /* Modification:- Function used to expect the bitmap of an object to be the dimensions of its bounding rectangle (ie bbox coords pixel aligned and dimensions converted to pixels, at current zoom) Given such a bitmap it expected to generate a bitmap which was nBlur pixels greater on all sides (ie dimensions increased by 2*nBlur) to cater for the amount of blurring which would extend beyond the dimensions of the src bitmap for any parts of the object which touched the src bitmaps border Feathering doesn't require this blurring outside the objects outline. Also we don't always pass in a full bitmap of the object. Modified the function to expect the src bitmap (ie pForegroundBits) to include the extra feathersized region which is needed to ensure that the bitmap lying nBlur pixels within the borders of the pForegroundBits is properly shadowed. Hence the intermediate version of the src bmp (from which the convolution is calculated) merely differs from pForeGroundBits in width, by DWORD alignment. The destination bitmap into which the convolution calculations are place, ForeGroundSize - 2*nBlur pixels, wide.(DWORD aligned?). Thus the destination bitmap is the same dimensions as the viewable rectangle ALSO changed to return lpBitmapInfo and modify a LPBYTE* USED to expect blur to be entire blur region (ie twice feather size) ie (from old code) double fNewBlur = fBlur/2.0 ; if ( fNewBlur>MAX_SHADOW_BLUR ) fNewBlur = MAX_SHADOW_BLUR ; UINT32 nBlur = (UINT32)fNewBlur ; Definition at line 166 of file fthrconv.cpp. 00167 { 00168 ERROR2IF(pSrcInfo->bmiHeader.biBitCount!=32, NULL, "Only supports 32bpp bitmap feathering"); 00169 00170 // Size of the original src bitmap 00171 CSize SrcBmpSize(pSrcInfo->bmiHeader.biWidth, pSrcInfo->bmiHeader.biHeight); 00172 CSize InnerBmpSizeCheck(SrcBmpSize.cx - 2*nBlur,SrcBmpSize.cy - 2*nBlur); 00173 // check convolution code will be OK 00174 if(!(InnerBmpSizeCheck.cx>1 && InnerBmpSizeCheck.cy>1)) 00175 { 00176 // Gavin's CompileCode asm function (called from GenerateWallShadow) can't handle this 00177 ENSURE(FALSE, "Conv code cannot create bmp with width or height of 1."); 00178 return NULL; 00179 } 00180 00182 // The pSrcBits32 have to be DWORD aligned 00184 // NB: OffscreenBMP's always 32Bpp. However if feathering an OffscreenBMP, the byte 00185 // width of pSrcInfo (ie pSrcInfo->bmiHeader.biWidth / 4) is won't always be DWORD 00186 // aligned (ie won't necessarily be an exact multiple of 4) 00187 // See note in GRenderRegion::CreateOffscreenState where buffer allocated 00188 const UINT32 DWordWidth = DIBUtil::ScanlineSize(SrcBmpSize.cx, 8); 00189 // Could be up to 3 pixels wider than the source 00190 UINT32 DWordPadding = DWordWidth - SrcBmpSize.cx; 00191 BOOL DWordAligned = (DWordPadding==0)? TRUE: FALSE; 00192 00193 CSize DWordSrcBmpSize(DWordWidth, SrcBmpSize.cy); 00194 00196 // Copy src into DWORD aligned 8bpp bmp to pass into gavin's routine (pBitmapToShadow) 00198 BYTE* pBitmapToShadow = new BYTE[DWordSrcBmpSize.cx*DWordSrcBmpSize.cy]; 00199 // If the src bmp requires no dword alignment. then we simply need to transfer T value of BGRT 00200 // pixel in the 32bpp src (ie 4th BYTE of every 4 BYTES) to pBitmapToShadow 00201 // 00202 // NB if src bitmap is the offscreen bmp, then it will be DWORD aligned. Also, our background 00203 // bits are pre-initialised to 0x000000FF. Hence anything outside the nodes path in the offscreen 00204 // bitmap will already have a T value of 0xFF. 00205 // 00206 // For non-DWORD aligned src bmps, we need to ensure that the DWORD padded bytes get set to 0xFF 00207 00208 // Now, set up the pointers to do the transfer of bits from one bitmap to the other 00209 // and move the destination pointer into position 00210 // CONST BYTE* pSrc = (CONST BYTE *)pSrcBits32 + 3 ; // T value of pSrcBits32 BGRT value 00211 CONST BYTE* pSrc = (CONST BYTE *)pSrcBits32; // R value of pSrcBits32 BGRT value 00212 BYTE* pDest = (BYTE *)pBitmapToShadow; 00213 00214 UINT32 ForegroundScanlineSize = SrcBmpSize.cx * 4; 00215 // transfer the source bitmap into this larger bitmap to be shadowed 00216 for ( UINT32 i=0 ; i<(UINT32)DWordSrcBmpSize.cy ; i++ ) 00217 { 00218 CONST BYTE* pNextSrcLine = pSrc +ForegroundScanlineSize; 00219 BYTE* pNextDestLine = pDest+DWordSrcBmpSize.cx; 00220 for ( UINT32 j=0 ; j<(UINT32)SrcBmpSize.cx ; j++ ) 00221 { 00222 *pDest++ = *pSrc; 00223 pSrc += 4; 00224 } 00225 00226 // set dword padding bits to background colour expected by convolution code 00227 if (!DWordAligned) 00228 { 00229 for(j=0; j<DWordPadding; j++) 00230 *pDest++ = 0xFF; // NB corresponds to memset(,0xFF,..) from bshadow.cpp code 00231 } 00232 00233 pSrc = pNextSrcLine; 00234 pDest = pNextDestLine; 00235 } 00236 00238 // Allocate dib for convolved bmp and set up info to pass to convolution function 00240 // Bitmap to shadow info headers 00241 BITMAPINFOHEADER SourceBI; 00242 SourceBI.biBitCount = 8; 00243 SourceBI.biWidth = SrcBmpSize.cx; 00244 SourceBI.biHeight = SrcBmpSize.cy; 00245 SourceBI.biPlanes = 1; 00246 00247 // Alloc a DIB to shadow into (also sets up info header) 00248 CSize InnerBmpSize(SrcBmpSize.cx - 2*nBlur,SrcBmpSize.cy - 2*nBlur); 00249 LPBITMAPINFO pDestInfo = AllocDIB( InnerBmpSize.cx, InnerBmpSize.cy, 8, pDestBits, NULL, TRUE); 00250 if(pDestInfo==NULL) 00251 { 00252 ENSURE(FALSE,"Failed to allocate space for shadow bitmap!"); 00253 delete [] pBitmapToShadow; 00254 return NULL; 00255 } 00256 pDestInfo->bmiHeader.biXPelsPerMeter = pSrcInfo->bmiHeader.biXPelsPerMeter; 00257 pDestInfo->bmiHeader.biYPelsPerMeter = pSrcInfo->bmiHeader.biYPelsPerMeter; 00258 00260 // set up the row & columns - a circular patch 00262 DWORD Left [CBitmapShadow::MAX_ROW_OFFSETS] ; 00263 DWORD Right[CBitmapShadow::MAX_ROW_OFFSETS] ; 00264 DWORD Low [CBitmapShadow::MAX_ROW_OFFSETS] ; 00265 DWORD High [CBitmapShadow::MAX_ROW_OFFSETS] ; 00266 UINT32 nSize = nBlur*2+1 ; 00267 double S = nBlur ; 00268 const double R2 = nBlur * nBlur; 00269 UINT32 nLine = nBlur ; 00270 UINT32 nArea = 0 ; 00271 UINT32 nRows = 0 ; 00272 for ( UINT32 r=0 ; r<nSize ; ++r ) 00273 { 00274 const double Radius2 = R2-S*S ; 00275 if ( Radius2>=0 ) 00276 { 00277 const UINT32 nRadius = FloorSqrt(Radius2) ; 00278 Left[nRows] = nLine-nRadius ; 00279 Right[nRows] = nLine+nRadius+1 ; 00280 if ( Left[nRows]<Right[nRows] ) 00281 { 00282 Low[nRows] = (nBlur-nRadius )*DWordSrcBmpSize.cx+r ; 00283 High[nRows] = (nBlur+nRadius+1)*DWordSrcBmpSize.cx+r ; 00284 nArea += Right[nRows]-Left[nRows] ; 00285 nRows++ ; 00286 } 00287 } 00288 S-- ; 00289 nLine += DWordSrcBmpSize.cx ; 00290 } 00291 00292 UINT32 nTableSize = nArea*255 ; 00293 UINT32 nInc = 0xffffffffu/nTableSize ; 00294 UINT32 nShift = 0 ; 00295 while ( nTableSize>=CBitmapShadow::TABLE_SIZE ) 00296 { 00297 nTableSize >>= 1 ; 00298 nShift++ ; 00299 } 00300 nInc <<= nShift ; 00301 BYTE* pTranslationTable = new BYTE[nTableSize+1] ; 00302 UINT32 nCount = 0 ; 00303 for ( i=0 ; i<=nTableSize ; ++i ) 00304 { 00305 pTranslationTable[i] = nCount>>24 ; 00306 nCount += nInc ; 00307 } 00308 00309 00311 // call gavin's routine to do the shadowing 00313 CBitmapShadow::GenerateWallShadow( 00314 &SourceBI, pBitmapToShadow, 00315 &pDestInfo->bmiHeader, *pDestBits, 00316 nRows, Left,Right, 00317 nRows, Low,High, 00318 nShift,pTranslationTable 00319 ) ; 00320 00322 // clean up intermediate bitmap and translation table 00324 delete [] pBitmapToShadow; 00325 delete [] pTranslationTable; 00326 00327 return pDestInfo; 00328 }
|
|
Definition at line 331 of file fthrconv.cpp. 00332 { 00333 ERROR2IF(pSrcInfo->bmiHeader.biBitCount!=8, NULL, "Only supports 8bpp bitmap feathering"); 00334 00335 // Size of the original src bitmap 00336 CSize SrcBmpSize(pSrcInfo->bmiHeader.biWidth, pSrcInfo->bmiHeader.biHeight); 00337 CSize InnerBmpSizeCheck(SrcBmpSize.cx - 2*nBlur,SrcBmpSize.cy - 2*nBlur); 00338 // check convolution code will be OK 00339 if(!(InnerBmpSizeCheck.cx>1 && InnerBmpSizeCheck.cy>1)) 00340 { 00341 // Gavin's CompileCode asm function (called from GenerateWallShadow) can't handle this 00342 ENSURE(FALSE, "Conv code cannot create bmp with width or height of 1."); 00343 return NULL; 00344 } 00345 00347 // The pSrcBits8 must already be DWORD aligned 00349 const UINT32 DWordWidth = DIBUtil::ScanlineSize(SrcBmpSize.cx, 8); 00350 // Could be up to 3 pixels wider than the source 00351 UINT32 DWordPadding = DWordWidth - SrcBmpSize.cx; 00352 BOOL DWordAligned = (DWordPadding==0)? TRUE: FALSE; 00353 00354 CSize DWordSrcBmpSize(DWordWidth, SrcBmpSize.cy); 00355 BYTE* pBitmapToShadow=NULL; 00356 if(DWordAligned) 00357 { 00358 pBitmapToShadow = pSrcBits8; 00359 } 00360 else 00361 { 00362 // assuming that 8bpp buffer is actually dword aligned 00363 // NB all buffers allocated by DIBUtil::Alloc dib are actually DWORD aligned even though 00364 // the bitmap info width/heigth info doesn't reflect this 00365 00366 pBitmapToShadow = pSrcBits8; 00367 } 00368 00370 // Allocate dib for convolved bmp and set up info to pass to convolution function 00372 // Bitmap to shadow info headers 00373 BITMAPINFOHEADER SourceBI; 00374 SourceBI.biBitCount = 8; 00375 SourceBI.biWidth = SrcBmpSize.cx; 00376 SourceBI.biHeight = SrcBmpSize.cy; 00377 SourceBI.biPlanes = 1; 00378 00379 // Alloc a DIB to shadow into (also sets up info header) 00380 CSize InnerBmpSize(SrcBmpSize.cx - 2*nBlur,SrcBmpSize.cy - 2*nBlur); 00381 LPBITMAPINFO pDestInfo = AllocDIB( InnerBmpSize.cx, InnerBmpSize.cy, 8, pDestBits, NULL, TRUE); 00382 if(pDestInfo==NULL) 00383 { 00384 ENSURE(FALSE,"Failed to allocate space for shadow bitmap!"); 00385 return NULL; 00386 } 00387 pDestInfo->bmiHeader.biXPelsPerMeter = pSrcInfo->bmiHeader.biXPelsPerMeter; 00388 pDestInfo->bmiHeader.biYPelsPerMeter = pSrcInfo->bmiHeader.biYPelsPerMeter; 00389 00391 // set up the row & columns - a circular patch 00393 DWORD Left [CBitmapShadow::MAX_ROW_OFFSETS] ; 00394 DWORD Right[CBitmapShadow::MAX_ROW_OFFSETS] ; 00395 DWORD Low [CBitmapShadow::MAX_ROW_OFFSETS] ; 00396 DWORD High [CBitmapShadow::MAX_ROW_OFFSETS] ; 00397 UINT32 nSize = nBlur*2+1 ; 00398 double S = nBlur ; 00399 const double R2 = nBlur * nBlur; 00400 UINT32 nLine = nBlur ; 00401 UINT32 nArea = 0 ; 00402 UINT32 nRows = 0 ; 00403 for ( UINT32 r=0 ; r<nSize ; ++r ) 00404 { 00405 const double Radius2 = R2-S*S ; 00406 if ( Radius2>=0 ) 00407 { 00408 const UINT32 nRadius = FloorSqrt(Radius2) ; 00409 Left[nRows] = nLine-nRadius ; 00410 Right[nRows] = nLine+nRadius+1 ; 00411 if ( Left[nRows]<Right[nRows] ) 00412 { 00413 Low[nRows] = (nBlur-nRadius )*DWordSrcBmpSize.cx+r ; 00414 High[nRows] = (nBlur+nRadius+1)*DWordSrcBmpSize.cx+r ; 00415 nArea += Right[nRows]-Left[nRows] ; 00416 nRows++ ; 00417 } 00418 } 00419 S-- ; 00420 nLine += DWordSrcBmpSize.cx ; 00421 } 00422 00423 UINT32 nTableSize = nArea*255 ; 00424 UINT32 nInc = 0xffffffffu/nTableSize ; 00425 UINT32 nShift = 0 ; 00426 while ( nTableSize>=CBitmapShadow::TABLE_SIZE ) 00427 { 00428 nTableSize >>= 1 ; 00429 nShift++ ; 00430 } 00431 nInc <<= nShift ; 00432 BYTE* pTranslationTable = new BYTE[nTableSize+1] ; 00433 UINT32 nCount = 0 ; 00434 for (UINT32 i=0 ; i<=nTableSize ; ++i ) 00435 { 00436 pTranslationTable[i] = nCount>>24 ; 00437 nCount += nInc ; 00438 } 00439 00440 00442 // call gavin's routine to do the shadowing 00444 CBitmapShadow::GenerateWallShadow( 00445 &SourceBI, pBitmapToShadow, 00446 &pDestInfo->bmiHeader, *pDestBits, 00447 nRows, Left,Right, 00448 nRows, Low,High, 00449 nShift,pTranslationTable 00450 ) ; 00451 00453 // clean up intermediate bitmap and translation table 00455 // delete [] pBitmapToShadow; 00456 delete [] pTranslationTable; 00457 00458 return pDestInfo; 00459 }
|
|
Definition at line 108 of file fthrconv.cpp. |