mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 01:37:16 +00:00
Composition Work 24 bit complete
This commit is contained in:
parent
519b12bffe
commit
148da3401d
@ -161,6 +161,19 @@ public:
|
||||
*/
|
||||
virtual void CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation) = 0;
|
||||
|
||||
/**
|
||||
* Build an alpha mask using this image
|
||||
* @param aTheMaskImage The image to build the mask from
|
||||
* @return true if the mask was set up.
|
||||
*/
|
||||
virtual PRBool SetAlphaMask(nsIImage *aTheMask) = 0;
|
||||
|
||||
/**
|
||||
* Move the alpha mask to this absolute location
|
||||
* @param the horiztonal location
|
||||
* @param the vertical location
|
||||
*/
|
||||
virtual void MoveAlphaMask(PRInt32 aX, PRInt32 aY) = 0;
|
||||
|
||||
//get the color space metrics for this image
|
||||
//virtual NI_ColorSpec * GetColorSpec() = 0; fix
|
||||
|
@ -210,7 +210,142 @@ nsImageWin::CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation)
|
||||
{
|
||||
|
||||
|
||||
// call the correct sub routine for each blend
|
||||
if( mNumBytesPixel==3 && ((nsImageWin*)aTheImage)->mNumBytesPixel==3)
|
||||
this->Comp24to24((nsImageWin*)aTheImage,aULLocation);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// lets build an alpha mask from this image
|
||||
PRBool
|
||||
nsImageWin::SetAlphaMask(nsIImage *aTheMask)
|
||||
{
|
||||
PRInt32 num;
|
||||
LPBYTE srcbits;
|
||||
|
||||
if(aTheMask && ((nsImageWin*)aTheMask)->mNumBytesPixel == 1)
|
||||
{
|
||||
mLocation.x = 0;
|
||||
mLocation.y = 0;
|
||||
mlphaDepth = 8;
|
||||
mAlphaWidth = aTheMask->GetWidth();
|
||||
mAlphaHeight = aTheMask->GetWidth();
|
||||
num = mAlphaWidth*mAlphaHeight;
|
||||
mARowBytes = aTheMask->GetLineStride();
|
||||
mAlphaBits = new unsigned char[mARowBytes * mAlphaHeight];
|
||||
|
||||
srcbits = aTheMask->GetBits();
|
||||
memcpy(mAlphaBits,srcbits,num);
|
||||
return(PR_TRUE);
|
||||
}
|
||||
|
||||
return(PR_FALSE);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// this routine has to flip the y, since the bits are in bottom scan
|
||||
// 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;
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
startx = irect.x;
|
||||
starty = this->GetHeight()-(irect.y+irect.height);
|
||||
d1 = mImageBits +(starty*dlinespan)+(3*startx);
|
||||
|
||||
// get the intersection relative to the source rectangle
|
||||
srect.SetRect(0,0,aTheImage->GetWidth(),aTheImage->GetHeight());
|
||||
drect = irect;
|
||||
drect.MoveBy(-aULLocation->x,-aULLocation->y);
|
||||
|
||||
drect.IntersectRect(drect,srect);
|
||||
slinespan = aTheImage->GetLineStride();
|
||||
startx = drect.x;
|
||||
starty = aTheImage->GetHeight() - (drect.y+drect.height);
|
||||
s1 = aTheImage->GetBits() + (starty*slinespan)+(3*startx);
|
||||
|
||||
if(mAlphaBits)
|
||||
{
|
||||
mlinespan = this->GetAlphaLineStride();
|
||||
m1 = mAlphaBits;
|
||||
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)/256.0;
|
||||
a2 = 1.0-a1;
|
||||
*d2 = (*d2)*a1 + (*s2)*a2;
|
||||
d2++;
|
||||
s2++;
|
||||
|
||||
*d2 = (*d2)*a1 + (*s2)*a2;
|
||||
d2++;
|
||||
s2++;
|
||||
|
||||
*d2 = (*d2)*a1 + (*s2)*a2;
|
||||
d2++;
|
||||
s2++;
|
||||
m2++;
|
||||
}
|
||||
s1 += slinespan;
|
||||
d1 += dlinespan;
|
||||
m1 += mlinespan;
|
||||
}
|
||||
}
|
||||
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)/2;
|
||||
d2++;
|
||||
s2++;
|
||||
}
|
||||
s1 += slinespan;
|
||||
d1 += dlinespan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -309,23 +444,39 @@ void nsImageWin :: ComputePaletteSize(PRIntn nBitCount)
|
||||
{
|
||||
case 8:
|
||||
mNumPalleteColors = 256;
|
||||
mNumBytesColor = 1;
|
||||
mNumBytesPixel = 1;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
mNumPalleteColors = 0;
|
||||
mNumBytesColor = 3;
|
||||
mNumBytesPixel = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
mNumPalleteColors = -1;
|
||||
mNumBytesColor = 0;
|
||||
mNumBytesPixel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
PRInt32 nsImageWin :: CalcBytesSpan(PRUint32 aWidth)
|
||||
{
|
||||
PRInt32 spanbytes;
|
||||
|
||||
spanbytes = (aWidth * mBHead->biBitCount) / 32;
|
||||
|
||||
if (((PRUint32)mBHead->biWidth * mBHead->biBitCount) % 32)
|
||||
spanbytes++;
|
||||
|
||||
spanbytes *= 4;
|
||||
|
||||
return(spanbytes);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
void nsImageWin :: ComputeMetrics()
|
||||
{
|
||||
|
||||
@ -333,12 +484,7 @@ void nsImageWin :: ComputeMetrics()
|
||||
|
||||
if (mSizeImage == 0)
|
||||
{
|
||||
mRowBytes = ((PRUint32) mBHead->biWidth * mBHead->biBitCount) / 32;
|
||||
|
||||
if (((PRUint32)mBHead->biWidth * mBHead->biBitCount) % 32)
|
||||
mRowBytes++;
|
||||
|
||||
mRowBytes *= 4;
|
||||
mRowBytes = CalcBytesSpan(mBHead->biWidth);
|
||||
mSizeImage = mRowBytes * mBHead->biHeight; // no compression
|
||||
}
|
||||
|
||||
@ -388,7 +534,7 @@ void nsImageWin :: CleanUp(PRBool aCleanUpAll)
|
||||
|
||||
mColorTable = nsnull;
|
||||
mNumPalleteColors = -1;
|
||||
mNumBytesColor = 0;
|
||||
mNumBytesPixel = 0;
|
||||
mSizeImage = 0;
|
||||
mHPalette = nsnull;
|
||||
mImageBits = nsnull;
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
virtual PRInt32 GetHeight() { return mBHead->biHeight; }
|
||||
virtual PRInt32 GetWidth() { return mBHead->biWidth; }
|
||||
virtual PRUint8* GetAlphaBits() { return mAlphaBits; }
|
||||
virtual PRInt32 GetAlphaLineStride(){ return mBHead->biWidth; }
|
||||
virtual PRInt32 GetAlphaLineStride(){ return mARowBytes; }
|
||||
virtual PRUint8* GetBits() { return mImageBits; }
|
||||
virtual PRInt32 GetLineStride() {return mRowBytes; }
|
||||
virtual PRBool Draw(nsDrawingSurface aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
@ -83,6 +83,18 @@ public:
|
||||
*/
|
||||
PRUintn UsePalette(HDC* aHdc, PRBool bBackground = PR_FALSE);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the number of bytes spaned for this image for a given width
|
||||
* @param aWidth is the width to calculate the number of bytes for
|
||||
* @return the number of bytes in this span
|
||||
*/
|
||||
PRInt32 CalcBytesSpan(PRUint32 aWidth);
|
||||
|
||||
PRBool SetAlphaMask(nsIImage *aTheMask);
|
||||
|
||||
void MoveAlphaMask(PRInt32 aX, PRInt32 aY){mLocation.x=aX;mLocation.y=aY;}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Clean up the memory used nsImageWin.
|
||||
@ -94,20 +106,33 @@ private:
|
||||
* Calculate the amount of memory needed for the palette
|
||||
* @param aBitCount is the number of bits per pixel
|
||||
*/
|
||||
|
||||
void ComputePaletteSize(PRIntn aBitCount);
|
||||
|
||||
/**
|
||||
* Composite a 24 bit image into another 24 bit image
|
||||
* @param aTheImage The image to blend into this image
|
||||
* @param aULLocation The upper left coordinate to place the passed in image
|
||||
*/
|
||||
void Comp24to24(nsImageWin *aTheImage,nsPoint *aULLocation);
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the amount of memory needed for the initialization of the pixelmap
|
||||
*/
|
||||
void ComputeMetrics();
|
||||
|
||||
PRInt8 mNumBytesColor; // number of bytes per color
|
||||
PRInt8 mNumBytesPixel; // number of bytes per pixel
|
||||
PRInt16 mNumPalleteColors; // either 8 or 0
|
||||
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
|
||||
PRInt16 mARowBytes;
|
||||
PRInt16 mAlphaWidth; // alpha layer width
|
||||
PRInt16 mAlphaHeight; // alpha layer height
|
||||
nsPoint mLocation; // alpha mask location
|
||||
PRBool mIsOptimized; // Have we turned our DIB into a GDI?
|
||||
nsColorMap *mColorMap; // Redundant with mColorTable, but necessary
|
||||
// for Set/GetColorMap
|
||||
@ -117,12 +142,4 @@ private:
|
||||
LPBITMAPINFOHEADER mBHead; // BITMAPINFOHEADER
|
||||
};
|
||||
|
||||
|
||||
/* TODO
|
||||
===================================
|
||||
1.) Share teh offscreen DC between other nsImageWin objects if nessasary
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
@ -55,9 +55,11 @@ static HWND gHwnd;
|
||||
static nsIWidget *gWindow = nsnull;
|
||||
static nsIImage *gImage = nsnull;
|
||||
static nsIImage *gBlendImage = nsnull;
|
||||
static nsIImage *gMaskImage = nsnull;
|
||||
static PRBool gInstalledColorMap = PR_FALSE;
|
||||
static PRInt32 gXOff,gYOff,gTestNum;
|
||||
|
||||
extern void Compositetest(nsIImage *aTheImage,nsIImage *aBlendImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY);
|
||||
extern void Compositetest(PRInt32 aTestNum,nsIImage *aImage,nsIImage *aBImage,nsIImage *aMImage, PRInt32 aX, PRInt32 aY);
|
||||
extern PRInt32 speedtest(nsIImage *aTheImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
extern PRInt32 drawtest(nsIRenderingContext *aSurface);
|
||||
extern PRInt32 filltest(nsIRenderingContext *aSurface);
|
||||
@ -66,7 +68,6 @@ extern PRBool IsImageLoaded();
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
||||
@ -77,7 +78,6 @@ private:
|
||||
|
||||
public:
|
||||
MyBlendObserver(nsIImage **aImage);
|
||||
//MyBlendObserver();
|
||||
~MyBlendObserver();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -128,33 +128,12 @@ MyBlendObserver::Notify(nsIImageRequest *aImageRequest,
|
||||
NS_ADDREF(aImage);
|
||||
}
|
||||
|
||||
|
||||
//if (gBlendImage == nsnull && aImage)
|
||||
//{
|
||||
//gBlendImage = aImage;
|
||||
//NS_ADDREF(aImage);
|
||||
//}
|
||||
|
||||
|
||||
if (!gInstalledColorMap && gBlendImage)
|
||||
if ( gBlendImage && (aNotificationType == nsImageNotification_kImageComplete) )
|
||||
{
|
||||
nsColorMap *cmap = (*mImage)->GetColorMap();
|
||||
|
||||
if(aNotificationType == nsImageNotification_kImageComplete)
|
||||
{
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
Compositetest(gImage,gBlendImage,drawCtx,0,0);
|
||||
}
|
||||
|
||||
//if (cmap != nsnull && cmap->NumColors > 0)
|
||||
//{
|
||||
//gWindow->SetColorMap(cmap);
|
||||
//}
|
||||
//gInstalledColorMap = PR_TRUE;
|
||||
nsRect *rect = (nsRect *)aParam3;
|
||||
Compositetest(gTestNum,gImage,gBlendImage,gMaskImage,gXOff,gYOff);
|
||||
}
|
||||
//nsRect *rect = (nsRect *)aParam3;
|
||||
//nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -187,8 +166,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
MyObserver::MyObserver()
|
||||
@ -267,15 +244,88 @@ MyObserver::NotifyError(nsIImageRequest *aImageRequest,
|
||||
|
||||
// This tests the compositing for the image
|
||||
void
|
||||
Compositetest(nsIImage *aTheImage,nsIImage *aBlendImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY)
|
||||
Compositetest(PRInt32 aTestNum,nsIImage *aImage,nsIImage *aBImage,nsIImage *aMImage, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
PRInt32 swidth, sheight,bwidth,bheight;
|
||||
|
||||
swidth = aTheImage->GetWidth();
|
||||
sheight = aTheImage->GetHeight();
|
||||
nsPoint *location;
|
||||
PRUint32 min,seconds,milli,i,h,w;
|
||||
SYSTEMTIME thetime;
|
||||
nsIRenderingContext *drawCtx = gWindow->GetRenderingContext();
|
||||
|
||||
if(aTestNum == 1)
|
||||
{
|
||||
location = new nsPoint(aX,aY);
|
||||
if(aMImage)
|
||||
{
|
||||
aImage->SetAlphaMask(aMImage);
|
||||
aImage->MoveAlphaMask(rand() % gImage->GetWidth(),rand() % gImage->GetHeight());
|
||||
}
|
||||
|
||||
if(aMImage == nsnull)
|
||||
{
|
||||
location->x = rand() % gImage->GetWidth();
|
||||
location->y = rand() % gImage->GetHeight();
|
||||
printf("\n Image Location is %d, %d\n", location->x,location->y);
|
||||
}
|
||||
|
||||
aImage->CompositeImage(aBImage,location);
|
||||
}
|
||||
|
||||
if(aTestNum == 2)
|
||||
{
|
||||
|
||||
if(aMImage)
|
||||
{
|
||||
aImage->SetAlphaMask(aMImage);
|
||||
}
|
||||
|
||||
printf("\nSTARTING Blending TEST\n");
|
||||
::GetSystemTime(&thetime);
|
||||
min = thetime.wMinute;
|
||||
seconds = thetime.wSecond;
|
||||
milli = thetime.wMilliseconds;
|
||||
location = new nsPoint(0,0);
|
||||
w = gImage->GetWidth();
|
||||
h = gImage->GetHeight();
|
||||
|
||||
if(aMImage)
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
else
|
||||
for(i=0;i<200;i++)
|
||||
{
|
||||
aImage->CompositeImage(aBImage,location);
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
}
|
||||
|
||||
::GetSystemTime(&thetime);
|
||||
min = thetime.wMinute-min;
|
||||
if(min>0)
|
||||
min = min*60;
|
||||
seconds = min+thetime.wSecond-seconds;
|
||||
if(seconds>0)
|
||||
seconds = (seconds*1000)+thetime.wMilliseconds;
|
||||
else
|
||||
seconds = thetime.wMilliseconds;
|
||||
milli=seconds-milli;
|
||||
|
||||
printf("The composite Time was %lu Milliseconds\n",milli);
|
||||
}
|
||||
|
||||
drawCtx->DrawImage(gImage, 0, 0, gImage->GetWidth(), gImage->GetHeight());
|
||||
|
||||
// we are finished with this
|
||||
if (gBlendImage)
|
||||
{
|
||||
NS_RELEASE(gBlendImage);
|
||||
gBlendImage = NULL;
|
||||
}
|
||||
|
||||
bwidth = aBlendImage->GetWidth();
|
||||
bheight = aBlendImage->GetHeight();
|
||||
}
|
||||
|
||||
|
||||
@ -639,6 +689,7 @@ long PASCAL
|
||||
WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
|
||||
{
|
||||
HMENU hMenu;
|
||||
char szFile[256];
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
@ -649,7 +700,6 @@ WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
|
||||
{
|
||||
case TIMER_OPEN:
|
||||
{
|
||||
char szFile[256];
|
||||
|
||||
if (!OpenFileDialog(szFile, 256))
|
||||
return 0L;
|
||||
@ -660,18 +710,31 @@ WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
|
||||
::DestroyWindow(hWnd);
|
||||
exit(0);
|
||||
break;
|
||||
case RDMSK:
|
||||
if (gMaskImage!=nsnull)
|
||||
{
|
||||
NS_RELEASE(gMaskImage);
|
||||
gMaskImage = nsnull;
|
||||
}
|
||||
if (OpenFileDialog(szFile, 256))
|
||||
MyLoadImage(szFile,PR_TRUE,&gMaskImage);
|
||||
break;
|
||||
case COMPTST:
|
||||
gTestNum = 1;
|
||||
case COMPTSTSPEED:
|
||||
if(LOWORD(param) == COMPTSTSPEED)
|
||||
gTestNum = 2;
|
||||
IsImageLoaded();
|
||||
if(gImage)
|
||||
{
|
||||
char szFile[256];
|
||||
|
||||
{
|
||||
if (gBlendImage!=nsnull)
|
||||
{
|
||||
NS_RELEASE(gBlendImage);
|
||||
gBlendImage = nsnull;
|
||||
}
|
||||
|
||||
gXOff = 100;
|
||||
gYOff = 100;
|
||||
if (OpenFileDialog(szFile, 256))
|
||||
MyLoadImage(szFile,PR_TRUE,&gBlendImage);
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ IMAGETEST MENU DISCARDABLE
|
||||
|
||||
POPUP "TEST"
|
||||
{
|
||||
MENUITEM "Composite Test", COMPTST
|
||||
MENUITEM "Read Mask", RDMSK
|
||||
MENUITEM "Composit Test", COMPTST
|
||||
MENUITEM "Composite Speed", COMPTSTSPEED
|
||||
MENUITEM "Blit Speed",BSTNOOPT
|
||||
MENUITEM "Blit Speed, Optimzed.",BSTOPT
|
||||
MENUITEM "Draw Test",DRAWTEST
|
||||
|
@ -28,5 +28,7 @@
|
||||
#define FILLTEST 40015
|
||||
#define ARCTEST 40016
|
||||
#define COMPTST 40017
|
||||
#define COMPTSTSPEED 40018
|
||||
#define RDMSK 40019
|
||||
|
||||
#endif /* resources_h___ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user