Fix frequent crash when dragging or copying images on Mac OS X. b=529910 r=josh r=joe

This commit is contained in:
Andrew Thompson 2010-03-25 12:07:36 -04:00
Родитель 986a7f435d
Коммит 709623cd51
4 изменённых файлов: 33 добавлений и 20 удалений

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

@ -451,8 +451,15 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
continue;
}
nsRefPtr<gfxImageSurface> frame;
rv = image->CopyFrame( imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE,
getter_AddRefs(frame));
if (NS_FAILED(rv) || !frame) {
continue;
}
CGImageRef imageRef = NULL;
nsresult rv = nsCocoaUtils::CreateCGImageFromImageContainer(image, imgIContainer::FRAME_CURRENT, &imageRef);
nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(frame, &imageRef);
if (NS_FAILED(rv) || !imageRef) {
continue;
}

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

@ -138,12 +138,11 @@ class nsCocoaUtils
/** Creates a <code>CGImageRef</code> from a frame contained in an <code>imgIContainer</code>.
Copies the pixel data from the indicated frame of the <code>imgIContainer</code> into a new <code>CGImageRef</code>.
The caller owns the <code>CGImageRef</code>.
@param aImage the image to extract a frame from
@param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
@param aFrame the frame to convert
@param aResult the resulting CGImageRef
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
*/
static nsresult CreateCGImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, CGImageRef *aResult);
static nsresult CreateCGImageFromSurface(gfxImageSurface *aFrame, CGImageRef *aResult);
/** Creates a Cocoa <code>NSImage</code> from a <code>CGImageRef</code>.
Copies the pixel data from the <code>CGImageRef</code> into a new <code>NSImage</code>.

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

@ -245,19 +245,12 @@ void nsCocoaUtils::CleanUpAfterNativeAppModalDialog()
NS_OBJC_END_TRY_ABORT_BLOCK;
}
nsresult nsCocoaUtils::CreateCGImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, CGImageRef *aResult)
nsresult nsCocoaUtils::CreateCGImageFromSurface(gfxImageSurface *aFrame, CGImageRef *aResult)
{
nsRefPtr<gfxImageSurface> frame;
nsresult rv = aImage->CopyFrame(aWhichFrame,
imgIContainer::FLAG_SYNC_DECODE,
getter_AddRefs(frame));
if (NS_FAILED(rv) || !frame) {
return NS_ERROR_FAILURE;
}
PRInt32 width = frame->Width();
PRInt32 stride = frame->Stride();
PRInt32 height = frame->Height();
PRInt32 width = aFrame->Width();
PRInt32 stride = aFrame->Stride();
PRInt32 height = aFrame->Height();
if ((stride % 4 != 0) || (height < 1) || (width < 1)) {
return NS_ERROR_FAILURE;
}
@ -266,7 +259,7 @@ nsresult nsCocoaUtils::CreateCGImageFromImageContainer(imgIContainer *aImage, PR
// the alpha ordering and endianness of the machine so we don't have to
// touch the bits ourselves.
CGDataProviderRef dataProvider = ::CGDataProviderCreateWithData(NULL,
frame->Data(),
aFrame->Data(),
stride * height,
NULL);
CGColorSpaceRef colorSpace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
@ -311,8 +304,15 @@ nsresult nsCocoaUtils::CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage
nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, NSImage **aResult)
{
nsRefPtr<gfxImageSurface> frame;
nsresult rv = aImage->CopyFrame(aWhichFrame,
imgIContainer::FLAG_SYNC_DECODE,
getter_AddRefs(frame));
if (NS_FAILED(rv) || !frame) {
return NS_ERROR_FAILURE;
}
CGImageRef imageRef = NULL;
nsresult rv = nsCocoaUtils::CreateCGImageFromImageContainer(aImage, aWhichFrame, &imageRef);
rv = nsCocoaUtils::CreateCGImageFromSurface(frame, &imageRef);
if (NS_FAILED(rv) || !imageRef) {
return NS_ERROR_FAILURE;
}

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

@ -439,10 +439,16 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
mImageRegionRect.SetRect(0, 0, origWidth, origHeight);
}
nsRefPtr<gfxImageSurface> frame;
nsresult rv = imageContainer->CopyFrame( imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE,
getter_AddRefs(frame));
if (NS_FAILED(rv) || !frame) {
[mNativeMenuItem setImage:nil];
return NS_ERROR_FAILURE;
}
CGImageRef origImage = NULL;
nsresult rv = nsCocoaUtils::CreateCGImageFromImageContainer(imageContainer,
imgIContainer::FRAME_CURRENT,
&origImage);
rv = nsCocoaUtils::CreateCGImageFromSurface(frame, &origImage);
if (NS_FAILED(rv) || !origImage) {
[mNativeMenuItem setImage:nil];
return NS_ERROR_FAILURE;
@ -487,6 +493,7 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
return NS_ERROR_FAILURE;
}
CGRect iconRect = ::CGRectMake(0, 0, kIconWidth, kIconHeight);
::CGContextClearRect(bitmapContext, iconRect);
::CGContextDrawImage(bitmapContext, iconRect, finalImage);
CGImageRef iconImage = ::CGBitmapContextCreateImage(bitmapContext);