Some more alpha blending, fixed some bugs and the test app now works
git-svn-id: svn://10.0.0.236/trunk@1295 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
013d1299c8
commit
332f4c19f3
@ -94,6 +94,30 @@ public:
|
||||
*/
|
||||
virtual PRUint8 * GetAlphaBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the width of the alpha mask
|
||||
@return The width in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaWidth() = 0;
|
||||
|
||||
/**
|
||||
* Get the height of the alpha mask
|
||||
@return The width in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaHeight() = 0;
|
||||
|
||||
/**
|
||||
* Get the x location of the upper corner of the alpha mask
|
||||
@return The x location in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaXLoc() = 0;
|
||||
|
||||
/**
|
||||
* Get the y location of the upper corner of the alpha mask
|
||||
@return The y location in pixels
|
||||
*/
|
||||
virtual PRInt32 GetAlphaYLoc() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes needed to get to the next scanline for the alpha mask
|
||||
@return The number of bytes in each scanline
|
||||
@ -175,6 +199,14 @@ public:
|
||||
*/
|
||||
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate this image and pass back new object to it
|
||||
* @param TheImage is the image to duplicate into this object
|
||||
* @return the new image
|
||||
*/
|
||||
virtual nsIImage* DuplicateImage() = 0;
|
||||
|
||||
//get the color space metrics for this image
|
||||
//virtual NI_ColorSpec * GetColorSpec() = 0; fix
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ nsresult nsImageWin :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
|
||||
if (mNumPalleteColors >= 0)
|
||||
{
|
||||
mBHead = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * mNumPalleteColors];
|
||||
mBHead->biSize = sizeof(BITMAPINFOHEADER);
|
||||
mBHead->biSize = sizeof(BITMAPINFOHEADER);
|
||||
mBHead->biWidth = aWidth;
|
||||
mBHead->biHeight = aHeight;
|
||||
mBHead->biPlanes = 1;
|
||||
@ -77,7 +77,17 @@ nsresult nsImageWin :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
|
||||
this->MakePalette();
|
||||
|
||||
if (aMaskRequirements != nsMaskRequirements_kNoMask)
|
||||
{
|
||||
mAlphaWidth=aWidth;
|
||||
mAlphaWidth=aHeight;
|
||||
mAlphaBits = new unsigned char[aWidth * aHeight];
|
||||
}
|
||||
else
|
||||
{
|
||||
mAlphaBits = 0;
|
||||
mAlphaWidth=0;
|
||||
mAlphaHeight=0;
|
||||
}
|
||||
|
||||
mColorMap = new nsColorMap;
|
||||
|
||||
@ -240,14 +250,14 @@ void nsImageWin::CompositeImage(nsIImage *aTheImage, nsPoint *aULLocation)
|
||||
// lets build an alpha mask from this image
|
||||
PRBool nsImageWin::SetAlphaMask(nsIImage *aTheMask)
|
||||
{
|
||||
PRInt32 num;
|
||||
LPBYTE srcbits;
|
||||
PRInt32 num;
|
||||
PRUint8 *srcbits;
|
||||
|
||||
if (aTheMask && (((nsImageWin*)aTheMask)->mNumBytesPixel == 1))
|
||||
{
|
||||
mLocation.x = 0;
|
||||
mLocation.y = 0;
|
||||
mlphaDepth = 8;
|
||||
mAlphaDepth = 8;
|
||||
mAlphaWidth = aTheMask->GetWidth();
|
||||
mAlphaHeight = aTheMask->GetWidth();
|
||||
num = mAlphaWidth*mAlphaHeight;
|
||||
@ -269,32 +279,34 @@ PRBool nsImageWin::SetAlphaMask(nsIImage *aTheMask)
|
||||
// line to top.
|
||||
void nsImageWin::Comp24to24(nsImageWin *aTheImage, nsPoint *aULLocation)
|
||||
{
|
||||
nsRect arect, srect, drect, irect;
|
||||
PRInt32 dlinespan, slinespan, mlinespan, startx, starty, numbytes, numlines, x, y;
|
||||
LPBYTE d1, d2, s1, s2, m1, m2;
|
||||
double a1, a2;
|
||||
nsRect arect,srect,drect,irect;
|
||||
PRInt32 dlinespan,slinespan,mlinespan,startx,starty,numbytes,numlines,x,y;
|
||||
PRInt16 temp;
|
||||
PRUint8 *alphabits, *d1,*d2,*s1,*s2,*m1,*m2;
|
||||
double a1,a2;
|
||||
|
||||
if (mAlphaBits)
|
||||
{
|
||||
x = mLocation.x;
|
||||
y = mLocation.y;
|
||||
arect.SetRect(0, 0, this->GetWidth(), this->GetHeight());
|
||||
srect.SetRect(mLocation.x, mLocation.y, mAlphaWidth, mAlphaHeight);
|
||||
arect.IntersectRect(arect, srect);
|
||||
}
|
||||
if( IsOptimized() )
|
||||
return;
|
||||
|
||||
alphabits = aTheImage->GetAlphaBits();
|
||||
if(alphabits)
|
||||
{
|
||||
arect.SetRect(0,0,this->GetWidth(),this->GetHeight());
|
||||
srect.SetRect(aTheImage->GetAlphaXLoc(),aTheImage->GetAlphaYLoc(),aTheImage->GetAlphaWidth(),aTheImage->GetAlphaHeight());
|
||||
arect.IntersectRect(arect,srect);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
arect.SetRect(0, 0, this->GetWidth(), this->GetHeight());
|
||||
x = y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
srect.SetRect(aULLocation->x, aULLocation->y, aTheImage->GetWidth(), aTheImage->GetHeight());
|
||||
drect = arect;
|
||||
|
||||
if (irect.IntersectRect(srect, drect))
|
||||
{
|
||||
{
|
||||
// calculate destination information
|
||||
|
||||
dlinespan = this->GetLineStride();
|
||||
numbytes = this->CalcBytesSpan(irect.width);
|
||||
numlines = irect.height;
|
||||
@ -313,33 +325,41 @@ void nsImageWin::Comp24to24(nsImageWin *aTheImage, nsPoint *aULLocation)
|
||||
starty = aTheImage->GetHeight() - (drect.y + drect.height);
|
||||
s1 = aTheImage->GetBits() + (starty * slinespan) + (3 * startx);
|
||||
|
||||
if (mAlphaBits)
|
||||
{
|
||||
mlinespan = this->GetAlphaLineStride();
|
||||
m1 = mAlphaBits;
|
||||
numbytes /= 3;
|
||||
if(alphabits)
|
||||
{
|
||||
mlinespan = aTheImage->GetAlphaLineStride();
|
||||
m1 = alphabits;
|
||||
numbytes/=3;
|
||||
|
||||
// now go thru the image and blend (remember, its bottom upwards)
|
||||
|
||||
for (y = 0; y < numlines; y++)
|
||||
{
|
||||
{
|
||||
s2 = s1;
|
||||
d2 = d1;
|
||||
m2 = m1;
|
||||
|
||||
for (x = 0; x < numbytes; x++)
|
||||
{
|
||||
a1 = (*m2) * (1.0 / 256.0);
|
||||
a2 = 1.0 - a1;
|
||||
*d2 = (PRUint8)((*d2) * a1 + (*s2) * a2);
|
||||
for(x=0;x<numbytes;x++)
|
||||
{
|
||||
a1 = (*m2)/256.0;
|
||||
a2 = 1.0-a1;
|
||||
temp = ((*d2)*a1 + (*s2)*a2);
|
||||
if(temp>255)
|
||||
temp = 255;
|
||||
*d2 = temp;
|
||||
d2++;
|
||||
s2++;
|
||||
|
||||
*d2 = (PRUint8)((*d2) * a1 + (*s2) * a2);
|
||||
temp = ((*d2)*a1 + (*s2)*a2);
|
||||
if(temp>255)
|
||||
temp = 255;
|
||||
*d2 = temp;
|
||||
d2++;
|
||||
s2++;
|
||||
|
||||
*d2 = (PRUint8)((*d2) * a1 + (*s2) * a2);
|
||||
temp = ((*d2)*a1 + (*s2)*a2);
|
||||
if(temp>255)
|
||||
temp = 255;
|
||||
*d2 = temp;
|
||||
d2++;
|
||||
s2++;
|
||||
m2++;
|
||||
@ -351,30 +371,115 @@ void nsImageWin::Comp24to24(nsImageWin *aTheImage, nsPoint *aULLocation)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
// now go thru the image and blend (remember, its bottom upwards)
|
||||
|
||||
for(y = 0; y < numlines; y++)
|
||||
{
|
||||
{
|
||||
s2 = s1;
|
||||
d2 = d1;
|
||||
|
||||
for(x = 0; x < numbytes; x++)
|
||||
{
|
||||
{
|
||||
*d2 = (*d2 + *s2) >> 1;
|
||||
d2++;
|
||||
s2++;
|
||||
}
|
||||
}
|
||||
|
||||
s1 += slinespan;
|
||||
d1 += dlinespan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
nsIImage*
|
||||
nsImageWin::DuplicateImage()
|
||||
{
|
||||
PRInt32 num,i;
|
||||
nsImageWin *theimage;
|
||||
PRUint8 *cpointer;
|
||||
|
||||
if( IsOptimized() )
|
||||
return nsnull;
|
||||
|
||||
theimage = new nsImageWin();
|
||||
NS_ADDREF(theimage);
|
||||
|
||||
// get the header and copy it
|
||||
theimage->mBHead = (LPBITMAPINFOHEADER)new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * theimage->mNumPalleteColors];
|
||||
//*(theimage->mBHead) = *(this->mBHead);
|
||||
num = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * theimage->mNumPalleteColors;
|
||||
memcpy(theimage->mBHead,this->mBHead,num);
|
||||
|
||||
// set in compute metrics
|
||||
theimage->mSizeImage = this->mSizeImage;
|
||||
theimage->mRowBytes = this->mRowBytes;
|
||||
theimage->mColorTable = (PRUint8 *)this->mBHead + sizeof(BITMAPINFOHEADER);
|
||||
theimage->mNumBytesPixel = this->mNumBytesPixel;
|
||||
theimage->mNumPalleteColors = this->mNumPalleteColors;
|
||||
theimage->mAlphaDepth = this->mAlphaDepth;
|
||||
theimage->mARowBytes = this->mARowBytes;
|
||||
theimage->mAlphaWidth = this->mAlphaWidth;
|
||||
theimage->mAlphaHeight = this->mAlphaHeight;
|
||||
theimage->mLocation = this->mLocation;
|
||||
theimage->mIsOptimized = this->mIsOptimized;
|
||||
|
||||
// set up the memory
|
||||
memset(mColorTable, 0, sizeof(RGBQUAD) * mNumPalleteColors);
|
||||
|
||||
// the bits of the image
|
||||
if(theimage->mSizeImage>0)
|
||||
{
|
||||
theimage->mImageBits = new unsigned char[theimage->mSizeImage];
|
||||
memcpy(theimage->mImageBits,this->mImageBits,theimage->mSizeImage);
|
||||
}
|
||||
else
|
||||
theimage->mImageBits = nsnull;
|
||||
|
||||
|
||||
// bits of the alpha mask
|
||||
num = theimage->mAlphaWidth*theimage->mAlphaHeight;
|
||||
if(num>0)
|
||||
{
|
||||
theimage->mAlphaBits = new unsigned char[num];
|
||||
memcpy(theimage->mImageBits,this->mImageBits,theimage->mSizeImage);
|
||||
}
|
||||
else
|
||||
theimage->mAlphaBits = nsnull;
|
||||
|
||||
theimage->mColorMap = new nsColorMap;
|
||||
if (theimage->mColorMap != nsnull)
|
||||
{
|
||||
theimage->mColorMap->NumColors = theimage->mNumPalleteColors;
|
||||
theimage->mColorMap->Index = new PRUint8[3 * theimage->mNumPalleteColors];
|
||||
memset(theimage->mColorMap->Index, 0, sizeof(PRUint8) * (3 * theimage->mNumPalleteColors));
|
||||
}
|
||||
|
||||
cpointer = theimage->mColorTable;
|
||||
for(i = 0; i < theimage->mColorMap->NumColors; i++)
|
||||
{
|
||||
theimage->mColorMap->Index[(3 * i) + 2] = this->mColorMap->Index[(3 * i) + 2];
|
||||
theimage->mColorMap->Index[(3 * i) + 1] = this->mColorMap->Index[(3 * i) + 1];
|
||||
theimage->mColorMap->Index[(3 * i)] = this->mColorMap->Index[(3 * i)];
|
||||
|
||||
*cpointer++ = theimage->mColorMap->Index[(3 * i) + 2];
|
||||
*cpointer++ = theimage->mColorMap->Index[(3 * i) + 1];
|
||||
*cpointer++ = theimage->mColorMap->Index[(3 * i)];
|
||||
*cpointer++ = 0;
|
||||
}
|
||||
|
||||
theimage->MakePalette();
|
||||
|
||||
theimage->mHBitmap = nsnull;
|
||||
|
||||
return (theimage);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRBool nsImageWin::MakePalette()
|
||||
{
|
||||
// makes a logical palette (mHPalette) from the DIB's color table
|
||||
@ -443,6 +548,8 @@ PRBool nsImageWin :: SetSystemPalette(HDC* aHdc)
|
||||
// creates an optimized bitmap, or HBITMAP
|
||||
nsresult nsImageWin :: Optimize(nsDrawingSurface aSurface)
|
||||
{
|
||||
return NS_OK; // TAKE THIS OUT
|
||||
|
||||
HDC the_hdc = (HDC)aSurface;
|
||||
|
||||
if ((the_hdc != NULL) && !IsOptimized() && (mSizeImage > 0))
|
||||
@ -521,6 +628,8 @@ void nsImageWin :: CleanUp(PRBool aCleanUpAll)
|
||||
// this only happens when we need to clean up everything
|
||||
if (aCleanUpAll == PR_TRUE)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (mAlphaBits != nsnull)
|
||||
delete [] mAlphaBits;
|
||||
|
||||
@ -528,13 +637,15 @@ void nsImageWin :: CleanUp(PRBool aCleanUpAll)
|
||||
::DeleteObject(mHBitmap);
|
||||
|
||||
if(mBHead)
|
||||
{
|
||||
delete[] mBHead;
|
||||
mBHead = nsnull;
|
||||
}
|
||||
|
||||
mHBitmap = nsnull;
|
||||
|
||||
mAlphaBits = nsnull;
|
||||
mIsOptimized = PR_FALSE;
|
||||
mBHead = nsnull;
|
||||
|
||||
if (mImageBits != nsnull)
|
||||
{
|
||||
@ -543,10 +654,6 @@ void nsImageWin :: CleanUp(PRBool aCleanUpAll)
|
||||
}
|
||||
}
|
||||
|
||||
// clean up the DIB
|
||||
if (mImageBits != nsnull)
|
||||
delete [] mImageBits;
|
||||
|
||||
if (mHPalette != nsnull)
|
||||
::DeleteObject(mHPalette);
|
||||
|
||||
|
||||
@ -35,19 +35,25 @@ public:
|
||||
*/
|
||||
virtual PRInt32 GetHeight() { return mBHead->biHeight; }
|
||||
virtual PRInt32 GetWidth() { return mBHead->biWidth; }
|
||||
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
|
||||
virtual PRInt32 GetAlphaLineStride(){ return mARowBytes; }
|
||||
virtual PRUint8* GetBits() { return mImageBits; }
|
||||
virtual PRInt32 GetLineStride() {return mRowBytes; }
|
||||
virtual PRBool Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
virtual PRBool Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
|
||||
virtual void CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation);
|
||||
virtual nsColorMap* GetColorMap() {return mColorMap;}
|
||||
virtual void ImageUpdated(PRUint8 aFlags, nsRect *aUpdateRect);
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
||||
virtual PRBool IsOptimized() { return mIsOptimized; }
|
||||
virtual nsresult Optimize(nsDrawingSurface aSurface);
|
||||
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
|
||||
virtual PRInt32 GetAlphaWidth() { return mAlphaWidth;}
|
||||
virtual PRInt32 GetAlphaHeight() {return mAlphaHeight;}
|
||||
virtual PRInt32 GetAlphaXLoc() {return mLocation.x;}
|
||||
virtual PRInt32 GetAlphaYLoc() {return mLocation.y;}
|
||||
virtual PRInt32 GetAlphaLineStride(){ return mARowBytes; }
|
||||
virtual void CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation);
|
||||
|
||||
virtual nsIImage* DuplicateImage();
|
||||
|
||||
/**
|
||||
* Return the header size of the Device Independent Bitmap(DIB).
|
||||
@ -126,9 +132,9 @@ private:
|
||||
PRInt32 mSizeImage; // number of bytes
|
||||
PRInt32 mRowBytes; // number of bytes per row
|
||||
PRUint8 *mColorTable; // color table for the bitmap
|
||||
LPBYTE mImageBits; // starting address of DIB bits
|
||||
LPBYTE mAlphaBits; // alpha layer if we made one
|
||||
PRInt8 mlphaDepth; // alpha layer depth
|
||||
PRUint8 *mImageBits; // starting address of DIB bits
|
||||
PRUint8 *mAlphaBits; // alpha layer if we made one
|
||||
PRInt8 mAlphaDepth; // alpha layer depth
|
||||
PRInt16 mARowBytes;
|
||||
PRInt16 mAlphaWidth; // alpha layer width
|
||||
PRInt16 mAlphaHeight; // alpha layer height
|
||||
|
||||
@ -131,7 +131,8 @@ MyBlendObserver::Notify(nsIImageRequest *aImageRequest,
|
||||
if ( gBlendImage && (aNotificationType == nsImageNotification_kImageComplete) )
|
||||
{
|
||||
nsColorMap *cmap = (*mImage)->GetColorMap();
|
||||
nsRect *rect = (nsRect *)aParam3;
|
||||
nsRect *rect = (nsRect *)aParam3;
|
||||
|
||||
Compositetest(gTestNum,gImage,gBlendImage,gMaskImage,gXOff,gYOff);
|
||||
}
|
||||
}
|
||||
@ -250,20 +251,22 @@ nsPoint *location;
|
||||
PRUint32 min,seconds,milli,i,h,w;
|
||||
SYSTEMTIME thetime;
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
nsIImage *theimage;
|
||||
|
||||
|
||||
if(aTestNum == 1)
|
||||
{
|
||||
location = new nsPoint(aX,aY);
|
||||
if(aMImage)
|
||||
{
|
||||
aImage->SetAlphaMask(aMImage);
|
||||
aImage->MoveAlphaMask(rand() % gImage->GetWidth(),rand() % gImage->GetHeight());
|
||||
aBImage->SetAlphaMask(aMImage);
|
||||
aBImage->MoveAlphaMask(rand() % aImage->GetWidth(),rand() % aImage->GetHeight());
|
||||
}
|
||||
|
||||
if(aMImage == nsnull)
|
||||
{
|
||||
location->x = rand() % gImage->GetWidth();
|
||||
location->y = rand() % gImage->GetHeight();
|
||||
location->x = rand() % aImage->GetWidth();
|
||||
location->y = rand() % aImage->GetHeight();
|
||||
printf("\n Image Location is %d, %d\n", location->x,location->y);
|
||||
}
|
||||
|
||||
@ -275,7 +278,7 @@ nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
|
||||
if(aMImage)
|
||||
{
|
||||
aImage->SetAlphaMask(aMImage);
|
||||
aBImage->SetAlphaMask(aMImage);
|
||||
}
|
||||
|
||||
printf("\nSTARTING Blending TEST\n");
|
||||
@ -283,7 +286,7 @@ nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
min = thetime.wMinute;
|
||||
seconds = thetime.wSecond;
|
||||
milli = thetime.wMilliseconds;
|
||||
location = new nsPoint(0,0);
|
||||
location = new nsPoint(aX,aY);
|
||||
w = gImage->GetWidth();
|
||||
h = gImage->GetHeight();
|
||||
|
||||
@ -291,16 +294,18 @@ nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
{
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
aImage->MoveAlphaMask(rand()%w,rand()%h);
|
||||
aImage->CompositeImage(aBImage,location);
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
aBImage->MoveAlphaMask(rand()%w,rand()%h);
|
||||
theimage = aImage->DuplicateImage();
|
||||
theimage->CompositeImage(aBImage,location);
|
||||
drawCtx->DrawImage(theimage, 0, 0, theimage->GetWidth(), theimage->GetHeight());
|
||||
NS_RELEASE(theimage);
|
||||
}
|
||||
}
|
||||
else
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
aImage->CompositeImage(aBImage,location);
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight());
|
||||
}
|
||||
|
||||
::GetSystemTime(&thetime);
|
||||
@ -317,7 +322,7 @@ nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
printf("The composite Time was %lu Milliseconds\n",milli);
|
||||
}
|
||||
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight());
|
||||
|
||||
// we are finished with this
|
||||
if (gBlendImage)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user