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:
dcone 1998-05-08 14:24:53 +00:00
parent 013d1299c8
commit 332f4c19f3
4 changed files with 212 additions and 62 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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)