diff --git a/mozilla/gfx/src/nsIImage.h b/mozilla/gfx/src/nsIImage.h index 6d4037226ef..eea64bae6b0 100644 --- a/mozilla/gfx/src/nsIImage.h +++ b/mozilla/gfx/src/nsIImage.h @@ -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 diff --git a/mozilla/gfx/src/windows/nsImageWin.cpp b/mozilla/gfx/src/windows/nsImageWin.cpp index 9b826c38a01..a61bf3e35cf 100644 --- a/mozilla/gfx/src/windows/nsImageWin.cpp +++ b/mozilla/gfx/src/windows/nsImageWin.cpp @@ -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;x255) + 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); diff --git a/mozilla/gfx/src/windows/nsImageWin.h b/mozilla/gfx/src/windows/nsImageWin.h index c3177a21879..56d89a88f67 100644 --- a/mozilla/gfx/src/windows/nsImageWin.h +++ b/mozilla/gfx/src/windows/nsImageWin.h @@ -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 diff --git a/mozilla/gfx/tests/btest/BitTest.cpp b/mozilla/gfx/tests/btest/BitTest.cpp index 3179edc2f38..e5b8f9b57bf 100644 --- a/mozilla/gfx/tests/btest/BitTest.cpp +++ b/mozilla/gfx/tests/btest/BitTest.cpp @@ -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)