Fix bugs 57327 and 57835; convert nsImageMac to use PixMaps rather than GWorlds to reduce memory usage, and reduce changes of allocation failure.

This commit is contained in:
sfraser%netscape.com 2001-01-02 23:16:50 +00:00
Родитель 58b1fc8673
Коммит 0d9777963a
3 изменённых файлов: 325 добавлений и 221 удалений

Просмотреть файл

@ -160,5 +160,36 @@ protected:
};
/** ------------------------------------------------------------
* Utility class for saving, locking, and restoring handle state
* Ok with null handle
*/
class StHandleLocker
{
public:
StHandleLocker(Handle theHandle)
: mHandle(theHandle)
{
if (mHandle)
{
mOldHandleState = ::HGetState(mHandle);
::HLock(mHandle);
}
}
~StHandleLocker()
{
if (mHandle)
::HSetState(mHandle, mOldHandleState);
}
protected:
Handle mHandle;
SInt8 mOldHandleState;
};
#endif // nsGfxUtils_h_

Просмотреть файл

@ -40,23 +40,27 @@ static NS_DEFINE_IID(kIImageIID, NS_IIMAGE_IID);
* @update
*/
nsImageMac::nsImageMac()
: mImageGWorld(nsnull)
: mImageBitsHandle(nsnull)
, mWidth(0)
, mHeight(0)
, mRowBytes(0)
, mBytesPerPixel(0)
, mAlphaGWorld(nsnull)
, mMaskBitsHandle(nsnull)
, mAlphaDepth(0)
, mAlphaWidth(0)
, mAlphaHeight(0)
, mARowBytes(0)
, mIsTopToBottom(PR_TRUE)
, mPixelDataSize(0)
, mNaturalWidth(0)
, mNaturalHeight(0)
, mNaturalWidth(0)
, mNaturalHeight(0)
{
NS_INIT_REFCNT();
::memset(&mImagePixmap, 0, sizeof(PixMap));
::memset(&mMaskPixmap, 0, sizeof(PixMap));
}
/** ---------------------------------------------------
@ -65,11 +69,22 @@ nsImageMac::nsImageMac()
*/
nsImageMac::~nsImageMac()
{
if (mImageGWorld)
::DisposeGWorld(mImageGWorld);
if (mImageBitsHandle)
::DisposeHandle(mImageBitsHandle);
if (mAlphaGWorld)
::DisposeGWorld(mAlphaGWorld);
if (mMaskBitsHandle)
::DisposeHandle(mMaskBitsHandle);
// dispose of the color tables if we have them
if (mImagePixmap.pmTable)
{
::DisposeCTable(mImagePixmap.pmTable);
}
if (mMaskPixmap.pmTable)
{
::DisposeCTable(mMaskPixmap.pmTable);
}
}
@ -82,23 +97,19 @@ NS_IMPL_ISUPPORTS(nsImageMac, kIImageIID);
PRUint8*
nsImageMac::GetBits()
{
if (!mImageGWorld)
if (!mImageBitsHandle)
{
NS_ASSERTION(0, "Getting bits for non-existent image");
return nsnull;
}
PixMapHandle thePixMap = ::GetGWorldPixMap(mImageGWorld);
// pixels should be locked here!
#if DEBUG
GWorldFlags pixelFlags = GetPixelsState(thePixMap);
NS_ASSERTION(pixelFlags & pixelsLocked, "Pixels must be locked here");
SInt8 pixelFlags = HGetState(mImageBitsHandle);
NS_ASSERTION(pixelFlags & (1 << 7), "Pixels must be locked here");
#endif
Ptr pixels = ::GetPixBaseAddr(thePixMap);
NS_ASSERTION(pixels, "Getting bits for image failed");
return (PRUint8 *)pixels;
return (PRUint8 *)*mImageBitsHandle;
}
@ -109,23 +120,19 @@ nsImageMac::GetBits()
PRUint8*
nsImageMac::GetAlphaBits()
{
if (!mAlphaGWorld)
if (!mMaskBitsHandle)
{
NS_ASSERTION(0, "Getting alpha bits for non-existent mask");
NS_ASSERTION(0, "Getting bits for non-existent image");
return nsnull;
}
PixMapHandle thePixMap = GetGWorldPixMap(mAlphaGWorld);
// pixels should be locked here!
#if DEBUG
GWorldFlags pixelFlags = GetPixelsState(thePixMap);
NS_ASSERTION(pixelFlags & pixelsLocked, "Pixels must be locked here");
SInt8 pixelFlags = HGetState(mMaskBitsHandle);
NS_ASSERTION(pixelFlags & (1 << 7), "Pixels must be locked here");
#endif
Ptr pixels = GetPixBaseAddr(thePixMap);
NS_ASSERTION(pixels, "Getting alpha bits failed");
return (PRUint8 *)pixels;
return (PRUint8 *)*mMaskBitsHandle;
}
@ -136,13 +143,20 @@ nsImageMac::GetAlphaBits()
nsresult
nsImageMac::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
{
OSErr err = noErr;
// have we already been initted?
if (mImageGWorld)
if (mImageBitsHandle)
{
NS_ASSERTION(0, "Initting image twice");
::DisposeGWorld(mImageGWorld);
mImageGWorld = nsnull;
::DisposeHandle(mImageBitsHandle);
mImageBitsHandle = nsnull;
if (mMaskBitsHandle) {
::DisposeHandle(mMaskBitsHandle);
mMaskBitsHandle = nsnull;
}
}
mWidth = aWidth;
@ -151,106 +165,52 @@ nsImageMac::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirem
SetNaturalWidth(0);
SetNaturalHeight(0);
PRInt16 bufferdepth;
err = CreatePixMap(aWidth, aHeight, aDepth, nsnull, mImagePixmap, mImageBitsHandle);
if (err != noErr)
{
if (err == memFullErr)
nsMemory::HeapMinimize(PR_FALSE);
return NS_ERROR_FAILURE;
}
switch(aDepth)
{
case 8:
//mThePixelmap.pmTable = ::GetCTable(8);
bufferdepth = 8;
break;
case 16:
bufferdepth = 16;
break;
case 24: // 24 and 32 bit are basically the same
case 32:
bufferdepth = 32;
break;
default:
NS_NOTREACHED("Unexpected buffer depth");
bufferdepth = 32;
break;
}
// allocate the GWorld
Rect bounds = {0, 0, 0, 0};
bounds.right = aWidth;
bounds.bottom = aHeight;
OSErr err = AllocateGWorld(bufferdepth, nsnull, bounds, &mImageGWorld);
if (err != noErr)
{
NS_WARNING("GWorld allocation failed");
nsMemory::HeapMinimize(PR_FALSE);
return NS_ERROR_OUT_OF_MEMORY;
}
//ClearGWorld(mImageGWorld);
// calculate the pixel data size
PixMapHandle thePixMap = ::GetGWorldPixMap(mImageGWorld);
mRowBytes = (**thePixMap).rowBytes & 0x3FFF;
mPixelDataSize = mRowBytes * aHeight;
mBytesPerPixel = (**thePixMap).cmpCount;
mRowBytes = mImagePixmap.rowBytes & 0x3FFF; // we only set the top bit, but QuickDraw can use the top 2 bits
if (aMaskRequirements != nsMaskRequirements_kNoMask)
{
PRInt16 mAlphaDepth = 0;
CTabHandle grayRamp = nsnull;
PRInt16 mAlphaDepth = 0;
switch (aMaskRequirements)
{
case nsMaskRequirements_kNeeds1Bit:
mAlphaDepth = 1;
err = AllocateGWorld(mAlphaDepth, nsnull, bounds, &mAlphaGWorld);
if (err != noErr)
{
nsMemory::HeapMinimize(PR_FALSE);
return NS_ERROR_OUT_OF_MEMORY;
}
break;
case nsMaskRequirements_kNeeds8Bit:
{
mAlphaDepth = 8;
// make 8-bit grayscale color table
CTabHandle grayRamp = nsnull;
/*
err = MakeGrayscaleColorTable(256, &grayRamp);
if (err != noErr)
return NS_ERROR_OUT_OF_MEMORY;
err = AllocateGWorld(mAlphaDepth, grayRamp, bounds, &mAlphaGWorld);
if (err != noErr)
{
nsMemory::HeapMinimize(PR_FALSE);
return NS_ERROR_OUT_OF_MEMORY;
}
::DisposeHandle((Handle)grayRamp);
*/
mAlphaDepth = 8;
break;
}
default:
NS_NOTREACHED("Uknown mask depth");
break;
}
if (mAlphaGWorld)
{
//ClearGWorld(mAlphaGWorld);
err = CreatePixMap(aWidth, aHeight, mAlphaDepth, grayRamp, mMaskPixmap, mMaskBitsHandle);
if (err != noErr)
{
if (err == memFullErr)
nsMemory::HeapMinimize(PR_FALSE);
return NS_ERROR_FAILURE;
}
// calculate the pixel data size
PixMapHandle maskPixMap = GetGWorldPixMap(mAlphaGWorld);
mARowBytes = (**maskPixMap).rowBytes & 0x3FFF;
mAlphaWidth = aWidth;
mAlphaHeight = aHeight;
}
mARowBytes = mMaskPixmap.rowBytes & 0x3FFF; // we only set the top bit, but QuickDraw can use the top 2 bits
mAlphaWidth = aWidth;
mAlphaHeight = aHeight;
}
return NS_OK;
@ -273,19 +233,25 @@ void nsImageMac::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect
NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, PRInt32 aSX, PRInt32 aSY,
PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
{
PixMapHandle imagePixMap;
Rect srcRect, dstRect, maskRect;
if (!mImageGWorld)
if (!mImageBitsHandle)
return NS_ERROR_FAILURE;
// lock and set up bits handles
StHandleLocker imageBitsLocker(mImageBitsHandle);
StHandleLocker maskBitsLocker(mMaskBitsHandle); // ok with nil handle
mImagePixmap.baseAddr = *mImageBitsHandle;
if (mMaskBitsHandle)
mMaskPixmap.baseAddr = *mMaskBitsHandle;
// currently the top is 0, this may change and this code will have to reflect that
if (( mDecodedY2 < aSHeight) ) {
// adjust the source and dest height to reflect this
aDHeight = float(mDecodedY2/float(aSHeight)) * aDHeight;
aSHeight = mDecodedY2;
}
}
::SetRect(&srcRect, aSX, aSY, aSX + aSWidth, aSY + aSHeight);
maskRect = srcRect;
@ -294,10 +260,6 @@ NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface a
::ForeColor(blackColor);
::BackColor(whiteColor);
imagePixMap = GetGWorldPixMap(mImageGWorld);
StPixelLocker pixelLocker(imagePixMap); // locks the pixels
// get the destination pix map
nsDrawingSurfaceMac* surface = static_cast<nsDrawingSurfaceMac*>(aSurface);
CGrafPtr destPort;
@ -312,9 +274,9 @@ NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface a
aContext.GetDeviceContext(*getter_AddRefs(theDevContext));
if (theDevContext->IsPrinter()) // we are printing
{
if (!mAlphaGWorld)
if (!mMaskBitsHandle)
{
::CopyBits((BitMap*)*imagePixMap, (BitMap*)*destPixels, &srcRect, &dstRect, srcCopy, nsnull);
::CopyBits((BitMap*)&mImagePixmap, (BitMap*)*destPixels, &srcRect, &dstRect, srcCopy, nsnull);
}
else
{
@ -323,7 +285,9 @@ NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface a
// if we have a mask, blit the transparent image into a new GWorld which is
// just white, and print that. This is marginally better than printing the
// image directly, since the transparent pixels come out black.
if (AllocateGWorld((**imagePixMap).packSize, nsnull, srcRect, &tempGWorld) == noErr)
// We do all this because Copy{Deep}Mask is not supported when printing
if (AllocateGWorld(mImagePixmap.packSize, nsnull, srcRect, &tempGWorld) == noErr)
{
// erase it to white
ClearGWorld(tempGWorld);
@ -337,13 +301,10 @@ NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface a
// for some reason this copies garbage, so we erase to white above instead.
// ::CopyBits((BitMap*)*destPixels, (BitMap*)*tempPixMap, &dstRect, &srcRect, srcCopy, nsnull);
PixMapHandle maskPixMap = GetGWorldPixMap(mAlphaGWorld);
StPixelLocker maskLocker(maskPixMap);
if (mAlphaDepth > 1)
::CopyDeepMask((BitMap*)*imagePixMap, (BitMap*)*maskPixMap, (BitMap*)*tempPixMap, &srcRect, &maskRect, &srcRect, srcCopy, nsnull);
::CopyDeepMask((BitMap*)&mImagePixmap, (BitMap*)&mMaskPixmap, (BitMap*)*tempPixMap, &srcRect, &maskRect, &srcRect, srcCopy, nsnull);
else
::CopyMask((BitMap*)*imagePixMap, (BitMap*)*maskPixMap, (BitMap*)*tempPixMap, &srcRect, &maskRect, &srcRect);
::CopyMask((BitMap*)&mImagePixmap, (BitMap*)&mMaskPixmap, (BitMap*)*tempPixMap, &srcRect, &maskRect, &srcRect);
// now copy to the screen
::CopyBits((BitMap*)*tempPixMap, (BitMap*)*destPixels, &srcRect, &dstRect, srcCopy, nsnull);
@ -355,19 +316,16 @@ NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface a
}
else // not printing
{
if (!mAlphaGWorld)
if (!mMaskBitsHandle)
{
::CopyBits((BitMap*)*imagePixMap, (BitMap*)*destPixels, &srcRect, &dstRect, srcCopy, nsnull);
::CopyBits((BitMap*)&mImagePixmap, (BitMap*)*destPixels, &srcRect, &dstRect, srcCopy, nsnull);
}
else
{
PixMapHandle maskPixMap = GetGWorldPixMap(mAlphaGWorld);
StPixelLocker maskLocker(maskPixMap);
if (mAlphaDepth > 1)
::CopyDeepMask((BitMap*)*imagePixMap, (BitMap*)*maskPixMap, (BitMap*)*destPixels, &srcRect, &maskRect, &dstRect, srcCopy, nsnull);
::CopyDeepMask((BitMap*)&mImagePixmap, (BitMap*)&mMaskPixmap, (BitMap*)*destPixels, &srcRect, &maskRect, &dstRect, srcCopy, nsnull);
else
::CopyMask((BitMap*)*imagePixMap, (BitMap*)*maskPixMap, (BitMap*)*destPixels, &srcRect, &maskRect, &dstRect);
::CopyMask((BitMap*)&mImagePixmap, (BitMap*)&mMaskPixmap, (BitMap*)*destPixels, &srcRect, &maskRect, &dstRect);
}
}
@ -427,14 +385,14 @@ PRInt32 nsImageMac::GetAlphaLevel()
NS_IMETHODIMP
nsImageMac::LockImagePixels(PRBool aMaskPixels)
{
if (!mImageGWorld)
if (!mImageBitsHandle)
return NS_ERROR_NOT_INITIALIZED;
if (aMaskPixels && !mAlphaGWorld)
if (aMaskPixels && !mMaskBitsHandle)
return NS_ERROR_NOT_INITIALIZED;
PixMapHandle thePixMap = ::GetGWorldPixMap(aMaskPixels ? mAlphaGWorld : mImageGWorld);
::LockPixels(thePixMap);
Handle thePixelsHandle = (aMaskPixels ? mMaskBitsHandle : mImageBitsHandle);
::HLock(thePixelsHandle);
return NS_OK;
}
@ -444,17 +402,178 @@ nsImageMac::LockImagePixels(PRBool aMaskPixels)
NS_IMETHODIMP
nsImageMac::UnlockImagePixels(PRBool aMaskPixels)
{
if (!mImageGWorld)
if (!mImageBitsHandle)
return NS_ERROR_NOT_INITIALIZED;
if (aMaskPixels && !mAlphaGWorld)
if (aMaskPixels && !mMaskBitsHandle)
return NS_ERROR_NOT_INITIALIZED;
PixMapHandle thePixMap = ::GetGWorldPixMap(aMaskPixels ? mAlphaGWorld : mImageGWorld);
::UnlockPixels(thePixMap);
Handle thePixelsHandle = (aMaskPixels ? mMaskBitsHandle : mImageBitsHandle);
::HUnlock(thePixelsHandle);
return NS_OK;
}
#pragma mark -
/** -----------------------------------------------------------------
* Create a PixMap, filling in ioPixMap
*/
OSErr nsImageMac::CreatePixMap(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, CTabHandle aColorTable, PixMap& ioPixMap, Handle& ioBitsHandle)
{
PRInt16 bufferdepth;
OSErr err = noErr;
ioPixMap.cmpCount = 0;
// See IM:QuickDraw pp 4-92 for GetCTable params
switch(aDepth)
{
case 1:
ioPixMap.pixelType = 0;
ioPixMap.cmpCount = 1;
ioPixMap.cmpSize = 1;
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 1); // default to black & white colortable
bufferdepth = 1;
break;
case 8:
ioPixMap.pixelType = 0;
ioPixMap.cmpCount = 1;
ioPixMap.cmpSize = 8;
ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 8); // default to gray ramp colortable
bufferdepth = 8;
break;
case 16:
ioPixMap.pixelType = RGBDirect;
ioPixMap.cmpCount = 3;
ioPixMap.cmpSize = 5;
ioPixMap.pmTable = nsnull;
bufferdepth = 16;
break;
case 24: // 24 and 32 bit are basically the same
case 32:
ioPixMap.pixelType = RGBDirect;
ioPixMap.cmpCount = 3;
ioPixMap.cmpSize = 8;
ioPixMap.pmTable = nsnull;
bufferdepth = 32;
break;
default:
NS_ASSERTION(0, "Unhandled image depth");
return paramErr;
}
if (ioPixMap.cmpCount)
{
PRInt32 imageSize;
PRInt32 rowBytes = CalculateRowBytes(aWidth, bufferdepth);
if (rowBytes >= 0x4000)
{
NS_ASSERTION(0, "PixMap too big for QuickDraw");
return paramErr;
}
imageSize = rowBytes * aHeight;
err = AllocateBitsHandle(imageSize, &ioBitsHandle);
if (err != noErr)
return err;
ioPixMap.baseAddr = nsnull; // We can only set this after locking the pixels handle
ioPixMap.rowBytes = rowBytes | 0x8000; // set the high bit to tell CopyBits that this is a PixMap
ioPixMap.bounds.top = 0;
ioPixMap.bounds.left = 0;
ioPixMap.bounds.bottom = aHeight;
ioPixMap.bounds.right = aWidth;
ioPixMap.pixelSize = bufferdepth;
ioPixMap.packType = 0;
ioPixMap.packSize = 0;
ioPixMap.hRes = nsDeviceContextMac::GetScreenResolution() << 16; // is this correct? printing?
ioPixMap.vRes = nsDeviceContextMac::GetScreenResolution() << 16;
#if TARGET_CARBON
ioPixMap.pixelFormat = 0; /*fourCharCode representation*/
ioPixMap.pmExt = 0;
#else
ioPixMap.planeBytes = 0;
ioPixMap.pmReserved = 0;
#endif
ioPixMap.pmVersion = 0;
}
return noErr;
}
/** -----------------------------------------------------------------
* Allocate bits handle, trying first in the heap, and then in temp mem.
*/
OSErr nsImageMac::AllocateBitsHandle(PRInt32 imageSizeBytes, Handle *outHandle)
{
*outHandle = nsnull;
// We have to be careful here not to fill the heap. //
// The strategy is this:
// 1. If we have plenty of heap space free, allocate the GWorld in
// the heap.
//
// 2. When below a certain threshold of free space in the heap,
// allocate GWorlds in temp mem.
//
// threshold at which we go to temp mem
const long kUseTempMemFreeSpace = (1024 * 1024);
const long kUseTempMemContigSpace = (768 * 1024);
long totalSpace, contiguousSpace;
::PurgeSpace(&totalSpace, &contiguousSpace); // this does not purge memory!
if (totalSpace > kUseTempMemFreeSpace && contiguousSpace > kUseTempMemContigSpace)
{
*outHandle = ::NewHandleClear(imageSizeBytes);
if (*outHandle) return noErr;
}
OSErr err;
*outHandle = ::TempNewHandle(imageSizeBytes, &err);
if (! *outHandle)
return memFullErr;
::BlockZero(**outHandle, imageSizeBytes);
return noErr;
}
/** ---------------------------------------------------
* Set the decoded dimens of the image
*/
NS_IMETHODIMP
nsImageMac::SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2 )
{
mDecodedX1 = x1;
mDecodedY1 = y1;
mDecodedX2 = x2;
mDecodedY2 = y2;
return NS_OK;
}
/** ---------------------------------------------------
* Calculate rowBytes, making sure that it comes out as
* a multiple of 4. ( 32 / 4 == 8)
* See <http://developer.apple.com/technotes/qd/qd_15.html>
*/
PRInt32 nsImageMac::CalculateRowBytes(PRUint32 aWidth, PRUint32 aDepth)
{
PRInt32 rowBytes = ((aWidth * aDepth + 31) / 32) * 4;
return rowBytes;
}
#pragma mark -
/** ---------------------------------------------------
@ -530,55 +649,3 @@ OSErr nsImageMac::AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rec
return memFullErr;
}
/** ----------------------------------------------------------
* Make a 256-level grayscale color table, for alpha blending.
* Caller must free the color table with ::DisposeHandle((Handle)colorTable)
* when done.
*/
OSErr nsImageMac::MakeGrayscaleColorTable(PRInt16 numColors, CTabHandle *outColorTable)
{
CTabHandle colorTable = nil;
colorTable = (CTabHandle)::NewHandleClear (8 * numColors + 8); /* Allocate memory for the table */
if (!colorTable) return memFullErr;
(**colorTable).ctSeed = ::GetCTSeed(); // not sure about this one
(**colorTable).ctFlags = 0; // not sure about this one
(**colorTable).ctSize = numColors - 1;
RGBColor tempColor = { 0xFFFF, 0xFFFF, 0xFFFF}; // starts at white
PRUint16 colorInc = 0xFFFF / numColors;
for (PRInt16 i = 0; i < numColors; i++)
{
(**colorTable).ctTable[i].value = i;
(**colorTable).ctTable[i].rgb = tempColor;
tempColor.red -= colorInc;
tempColor.green -= colorInc;
tempColor.blue -= colorInc;
}
*outColorTable = colorTable;
return noErr;
}
/** ---------------------------------------------------
* Set the decoded dimens of the image
*/
NS_IMETHODIMP
nsImageMac::SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2 )
{
mDecodedX1 = x1;
mDecodedY1 = y1;
mDecodedX2 = x2;
mDecodedY2 = y2;
return NS_OK;
}

Просмотреть файл

@ -46,34 +46,34 @@ public:
virtual PRUint8* GetBits();
virtual PRInt32 GetLineStride() { return mRowBytes; }
virtual PRBool GetHasAlphaMask() { return mAlphaGWorld != nsnull; }
virtual PRBool GetHasAlphaMask() { return mMaskBitsHandle != nsnull; }
NS_IMETHOD SetNaturalWidth(PRInt32 naturalwidth) { mNaturalWidth= naturalwidth; return NS_OK;}
NS_IMETHOD SetNaturalHeight(PRInt32 naturalheight) { mNaturalHeight= naturalheight; return NS_OK;}
virtual PRInt32 GetNaturalWidth() {return mNaturalWidth; }
virtual PRInt32 GetNaturalHeight() {return mNaturalHeight; }
NS_IMETHOD SetNaturalWidth(PRInt32 naturalwidth) { mNaturalWidth= naturalwidth; return NS_OK;}
NS_IMETHOD SetNaturalHeight(PRInt32 naturalheight) { mNaturalHeight= naturalheight; return NS_OK;}
virtual PRInt32 GetNaturalWidth() {return mNaturalWidth; }
virtual PRInt32 GetNaturalHeight() {return mNaturalHeight; }
NS_IMETHOD SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2);
virtual PRInt32 GetDecodedX1() { return mDecodedX1;}
virtual PRInt32 GetDecodedY1() { return mDecodedY1;}
virtual PRInt32 GetDecodedX2() { return mDecodedX2;}
virtual PRInt32 GetDecodedY2() { return mDecodedY2;}
NS_IMETHOD SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2);
virtual PRInt32 GetDecodedX1() { return mDecodedX1;}
virtual PRInt32 GetDecodedY1() { return mDecodedY1;}
virtual PRInt32 GetDecodedX2() { return mDecodedX2;}
virtual PRInt32 GetDecodedY2() { return mDecodedY2;}
virtual PRUint8* GetAlphaBits();
virtual PRInt32 GetAlphaWidth() { return mAlphaWidth; }
virtual PRInt32 GetAlphaHeight() { return mAlphaHeight; }
virtual PRInt32 GetAlphaWidth() { return mAlphaWidth; }
virtual PRInt32 GetAlphaHeight() { return mAlphaHeight; }
virtual PRInt32 GetAlphaLineStride() { return mARowBytes; }
virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
virtual PRBool IsOptimized() { return PR_FALSE; }
virtual nsresult Optimize(nsIDeviceContext* aContext);
virtual nsColorMap* GetColorMap() { return nsnull;}
virtual nsColorMap* GetColorMap() { return nsnull;}
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
NS_IMETHOD Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight);
@ -85,14 +85,19 @@ public:
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
protected:
void ClearGWorld(GWorldPtr);
OSErr MakeGrayscaleColorTable(PRInt16 numColors, CTabHandle *outColorTable);
OSErr AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rect& bounds, GWorldPtr *outGWorld);
static OSErr CreatePixMap(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, CTabHandle aColorTable,
PixMap& ioPixMap, Handle& ioBitsHandle);
static OSErr AllocateBitsHandle(PRInt32 imageSizeBytes, Handle *outHandle);
static PRInt32 CalculateRowBytes(PRUint32 aWidth,PRUint32 aDepth);
static void ClearGWorld(GWorldPtr);
static OSErr AllocateGWorld(PRInt16 depth, CTabHandle colorTable, const Rect& bounds, GWorldPtr *outGWorld);
private:
GWorldPtr mImageGWorld;
PixMap mImagePixmap;
Handle mImageBitsHandle; // handle for the image bits
PRInt32 mWidth;
PRInt32 mHeight;
@ -101,22 +106,23 @@ private:
PRInt32 mBytesPerPixel;
// alpha layer members
GWorldPtr mAlphaGWorld;
PixMap mMaskPixmap; // the alpha level pixel map
Handle mMaskBitsHandle; // handle for the mask bits
PRInt16 mAlphaDepth; // alpha layer depth
PRInt16 mAlphaWidth; // alpha layer width
PRInt16 mAlphaHeight; // alpha layer height
PRInt32 mARowBytes; // alpha row bytes
PRInt32 mNaturalWidth;
PRInt32 mNaturalHeight;
PRInt32 mNaturalWidth;
PRInt32 mNaturalHeight;
PRInt32 mDecodedX1; //Keeps track of what part of image
PRInt32 mDecodedY1; // has been decoded.
PRInt32 mDecodedX2;
PRInt32 mDecodedY2;
PRInt32 mDecodedX1; //Keeps track of what part of image
PRInt32 mDecodedY1; // has been decoded.
PRInt32 mDecodedX2;
PRInt32 mDecodedY2;
//nsPoint mLocation; // alpha mask location
//PRInt8 mImageCache; // place to save off the old image for fast animation