Fix for bug 119118 Issue with calculating rowBytes. r=sdagley, sr=smfr

This commit is contained in:
lordpixel%mac.com 2002-01-24 03:48:54 +00:00
Родитель bb256723c2
Коммит 199198044b
1 изменённых файлов: 81 добавлений и 31 удалений

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

@ -483,6 +483,19 @@ nsImageMac::UnlockImagePixels(PRBool aMaskPixels)
OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth, CTabHandle aColorTable,
PixMap& ioPixMap, Handle& ioBitsHandle)
{
CreatePixMapInternal( aWidth, aHeight, aDepth, aColorTable,
ioPixMap, ioBitsHandle, PR_FALSE);
}
/** -----------------------------------------------------------------
* Create a PixMap, filling in ioPixMap
* Call the CreatePixMap wrapper instead.
*/
OSErr nsImageMac::CreatePixMapInternal( PRInt32 aWidth, PRInt32 aHeight,
PRInt32 aDepth, CTabHandle aColorTable,
PixMap& ioPixMap, Handle& ioBitsHandle, PRBool aAllow2Bytes)
{
PRInt16 bufferdepth;
OSErr err = noErr;
@ -564,8 +577,8 @@ OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight,
if (ioPixMap.cmpCount)
{
PRInt32 imageSize;
PRInt32 rowBytes = CalculateRowBytes(aWidth, ioPixMap.pixelSize);
PRInt32 rowBytes = CalculateRowBytesInternal(aWidth, ioPixMap.pixelSize, aAllow2Bytes);
if (rowBytes >= 0x4000)
{
NS_ASSERTION(0, "PixMap too big for QuickDraw");
@ -660,22 +673,38 @@ nsImageMac::SetDecodedRect(PRInt32 x1, PRInt32 y1, PRInt32 x2, PRInt32 y2 )
/** ---------------------------------------------------
* Calculate rowBytes, making sure that it comes out as
* a multiple of 4. ( 32 / 4 == 8)
* a multiple of 4. ( 32 / 4 == 8). If you pass true for
* aAllow2Bytes then, for small images (aWidth * aDepth =< 24), you
* get a result which can be a multiple of 2 instead.
* Some parts of the toolbox require this, notably the native icon creation
* code. This is worth experimenting with if you deal with masks of 16x16 icons
* which are frequently 1 bit and thus are considered "small" by this function.
*
* CAUTION: MacOS X is extremely intolerant of divisible by 2 widths. You should never
* pass a PixMap to the OS for drawing with PixMap.rowBytes set to anything other than
* a multiple of 4 on Mac OS X. (CopyBits seems to be OK with divisible by 2 rowbytes,
* at least for the icon code in this class). That's why this function is private and
* wrapped.
*
* See <http://developer.apple.com/technotes/qd/qd_15.html>
*/
PRInt32 nsImageMac::CalculateRowBytes(PRUint32 aWidth, PRUint32 aDepth)
PRInt32 nsImageMac::CalculateRowBytesInternal(PRUint32 aWidth, PRUint32 aDepth, PRBool aAllow2Bytes)
{
PRInt32 rowBits = aWidth * aDepth;
PRInt32 rowBytes;
// if bits per row is 24 or less, needs 3 bytes or less
if (rowBits > 24)
rowBytes = ((aWidth * aDepth + 31) / 32) * 4;
else
rowBytes = ((aWidth * aDepth + 15) / 16) * 2;
return rowBytes;
//if bits per row is 24 or less, may need 3 bytes or less
return (rowBits > 24 || !aAllow2Bytes) ?
((aWidth * aDepth + 31) / 32) * 4 :
((aWidth * aDepth + 15) / 16) * 2;
}
/** Protected CalculateRowBytes. Most functions should call this
Requires rowBytes to be a multiple of 4
@see CalculateRowBytesInternal
*/
PRInt32 nsImageMac::CalculateRowBytes(PRUint32 aWidth, PRUint32 aDepth)
{
CalculateRowBytesInternal(aWidth, aDepth, PR_FALSE);
}
#pragma mark -
@ -929,8 +958,8 @@ nsImageMac::ConvertToIcon( const nsRect& aSrcRegion,
srcRect.bottom = aSrcRegion.y + aSrcRegion.height;
srcRect.right = aSrcRegion.x + aSrcRegion.width;
return CopyPixMap( srcRect, iconRect, aIconDepth,
PR_FALSE, aOutIcon);
return CopyPixMapInternal( srcRect, iconRect, aIconDepth,
PR_FALSE, aOutIcon, PR_TRUE);
} // ConvertToIcon
/** Create an Icon mask from a specified region of the the alpha channel
@ -1018,18 +1047,18 @@ nsImageMac::ConvertAlphaToIconMask( const nsRect& aSrcRegion,
//mask, or vice versa, it'll simply be converted by CopyPixMap
if (aMaskDepth == 8) {
//for 8 bit masks, this is sufficient
result = CopyPixMap( srcRect, maskRect, aMaskDepth,
PR_TRUE, &dstHandle);
result = CopyPixMapInternal(srcRect, maskRect, aMaskDepth,
PR_TRUE, &dstHandle, PR_TRUE);
} else if (aMaskDepth == 1) {
//1 bit masks are tricker, we must create an '#' resource
//which inclues both the 1-bit icon and a mask for it (icm#, ics#, ICN# or ich#)
Handle iconHandle = nsnull, maskHandle = nsnull;
result = CopyPixMap( srcRect, maskRect, aMaskDepth,
PR_FALSE, &iconHandle);
result = CopyPixMapInternal(srcRect, maskRect, aMaskDepth,
PR_FALSE, &iconHandle, PR_TRUE);
if (NS_SUCCEEDED(result)) {
result = CopyPixMap( srcRect, maskRect, aMaskDepth,
PR_TRUE, &maskHandle);
result = CopyPixMapInternal(srcRect, maskRect, aMaskDepth,
PR_TRUE, &maskHandle, PR_TRUE);
if (NS_SUCCEEDED(result)) {
//a '#' resource's data is simply the mask appended to the icon
//these icons and masks are small - 128 bytes each
@ -1051,7 +1080,7 @@ nsImageMac::ConvertAlphaToIconMask( const nsRect& aSrcRegion,
} else if (aMaskDepth == 1) {
//make 1 bit icon and mask as above
Handle iconHandle = nsnull, maskHandle = nsnull;
result = CopyPixMap( srcRect, maskRect, aMaskDepth, PR_FALSE, &iconHandle);
result = CopyPixMapInternal( srcRect, maskRect, aMaskDepth, PR_FALSE, &iconHandle, PR_TRUE);
if (NS_SUCCEEDED(result)) {
result = MakeOpaqueMask(aMaskSize, aMaskSize, aMaskDepth, &maskHandle);
if (NS_SUCCEEDED(result)) {
@ -1095,12 +1124,32 @@ nsImageMac::ConvertAlphaToIconMask( const nsRect& aSrcRegion,
is responsible for disposing of them
*/
nsresult
nsImageMac::CopyPixMap ( Rect& aSrcRegion,
nsImageMac::CopyPixMap(Rect& aSrcRegion,
Rect& aDestRegion,
const PRInt32 aDestDepth,
const PRBool aCopyMaskBits,
Handle *aDestData
)
{
CopyPixMapInternal(aSrcRegion,
aDestRegion,
aDestDepth,
aCopyMaskBits,
aDestData,
PR_FALSE);
}
/** Call CopyPixMap instead*/
nsresult
nsImageMac::CopyPixMapInternal(Rect& aSrcRegion,
Rect& aDestRegion,
const PRInt32 aDestDepth,
const PRBool aCopyMaskBits,
Handle *aDestData
)
Handle *aDestData,
PRBool aAllow2Bytes
)
{
OSStatus err;
PRBool pixelsNeedLocking = PR_FALSE;
@ -1138,12 +1187,13 @@ nsImageMac::CopyPixMap ( Rect& aSrcRegion,
}
// allocate the PixMap structure, then fill it out
err = CreatePixMap( aDestRegion.right - aDestRegion.left,
aDestRegion.bottom - aDestRegion.top,
aDestDepth,
destColorTable,
destPixmap,
resultData);
err = CreatePixMapInternal( aDestRegion.right - aDestRegion.left,
aDestRegion.bottom - aDestRegion.top,
aDestDepth,
destColorTable,
destPixmap,
resultData,
aAllow2Bytes);
if(err) {
return NS_ERROR_FAILURE;
}
@ -1237,7 +1287,7 @@ nsImageMac::MakeOpaqueMask( const PRInt32 aWidth,
Handle *aMask)
{
//mask size = (width * height * depth)
PRInt32 size = aHeight * CalculateRowBytes(aWidth, aDepth);
PRInt32 size = aHeight * CalculateRowBytesInternal(aWidth, aDepth, PR_TRUE);
OSStatus err;
Handle resultData = nsnull;