fthrconv.h File Reference

(r1785/r751)

Go to the source code of this file.

Functions

LPBITMAPINFO Shadow32BppBitmap (const UINT32 nBlur, LPBITMAPINFO pSrcInfo, LPBYTE pSrcBits32, LPBYTE *pDestBits)
LPBITMAPINFO Shadow8BppBitmap (const UINT32 nBlur, LPBITMAPINFO pSrcInfo, LPBYTE pSrcBits32, LPBYTE *pDestBits)


Function Documentation

LPBITMAPINFO Shadow32BppBitmap const UINT32  nBlur,
LPBITMAPINFO  pSrcInfo,
LPBYTE  pSrcBits32,
LPBYTE pDestBits
 

/

/* 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 }

LPBITMAPINFO Shadow8BppBitmap const UINT32  nBlur,
LPBITMAPINFO  pSrcInfo,
LPBYTE  pSrcBits32,
LPBYTE pDestBits
 

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 }


Generated on Sat Nov 10 03:49:10 2007 for Camelot by  doxygen 1.4.4