Bug 950368 - Make nsWindowsShellService's WriteBitmap act on a Moz2D SourceSurface instead of a Thebes gfxASurface. r=mattwoodrow

This commit is contained in:
Jonathan Watt 2014-03-04 16:56:44 +00:00
parent 1706c755f4
commit 4b64c371e1
2 changed files with 30 additions and 16 deletions

View File

@ -5,6 +5,8 @@
#include "imgIContainer.h" #include "imgIContainer.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDOMHTMLImageElement.h" #include "nsIDOMHTMLImageElement.h"
#include "nsIImageLoadingContent.h" #include "nsIImageLoadingContent.h"
@ -55,6 +57,8 @@
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1" #define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
using mozilla::IsWin8OrLater; using mozilla::IsWin8OrLater;
using namespace mozilla;
using namespace mozilla::gfx;
NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService) NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService)
@ -749,21 +753,30 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
{ {
nsresult rv; nsresult rv;
nsRefPtr<gfxASurface> surface = nsRefPtr<gfxASurface> thebesSurface =
aImage->GetFrame(imgIContainer::FRAME_FIRST, aImage->GetFrame(imgIContainer::FRAME_FIRST,
imgIContainer::FLAG_SYNC_DECODE); imgIContainer::FLAG_SYNC_DECODE);
NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE); NS_ENSURE_TRUE(thebesSurface, NS_ERROR_FAILURE);
nsRefPtr<gfxImageSurface> image(surface->GetAsReadableARGB32ImageSurface()); nsRefPtr<gfxImageSurface> thebesImageSurface =
NS_ENSURE_TRUE(image, NS_ERROR_FAILURE); thebesSurface->GetAsReadableARGB32ImageSurface();
NS_ENSURE_TRUE(thebesImageSurface, NS_ERROR_FAILURE);
int32_t width = image->Width(); RefPtr<DataSourceSurface> dataSurface =
int32_t height = image->Height(); thebesImageSurface->CopyToB8G8R8A8DataSourceSurface();
NS_ENSURE_TRUE(dataSurface, NS_ERROR_FAILURE);
uint8_t* bits = image->Data(); DataSourceSurface::MappedSurface map;
uint32_t length = image->GetDataSize(); dataSurface->Map(DataSourceSurface::MapType::READ, &map);
uint32_t bpr = uint32_t(image->Stride()); if (!map.mData) {
int32_t bitCount = bpr/width; return NS_ERROR_FAILURE;
}
int32_t width = dataSurface->GetSize().width;
int32_t height = dataSurface->GetSize().height;
int32_t bytesPerPixel = 4 * sizeof(uint8_t);
uint32_t bytesPerRow = bytesPerPixel * width;
uint32_t length = map.mStride * height;
// initialize these bitmap structs which we will later // initialize these bitmap structs which we will later
// serialize directly to the head of the bitmap file // serialize directly to the head of the bitmap file
@ -772,9 +785,9 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
bmi.biWidth = width; bmi.biWidth = width;
bmi.biHeight = height; bmi.biHeight = height;
bmi.biPlanes = 1; bmi.biPlanes = 1;
bmi.biBitCount = (WORD)bitCount*8; bmi.biBitCount = (WORD)bytesPerPixel*8;
bmi.biCompression = BI_RGB; bmi.biCompression = BI_RGB;
bmi.biSizeImage = length; bmi.biSizeImage = bytesPerRow * height;
bmi.biXPelsPerMeter = 0; bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0; bmi.biYPelsPerMeter = 0;
bmi.biClrUsed = 0; bmi.biClrUsed = 0;
@ -804,9 +817,9 @@ WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
// show bitmaps with negative heights for top-to-bottom // show bitmaps with negative heights for top-to-bottom
uint32_t i = length; uint32_t i = length;
do { do {
i -= bpr; i -= map.mStride;
stream->Write(((const char*)bits) + i, bpr, &written); stream->Write(((const char*)map.mData) + i, bytesPerRow, &written);
if (written == bpr) { if (written == bytesPerRow) {
rv = NS_OK; rv = NS_OK;
} else { } else {
rv = NS_ERROR_FAILURE; rv = NS_ERROR_FAILURE;

View File

@ -112,8 +112,9 @@ public:
/** /**
* Copy to a Moz2D DataSourceSurface. * Copy to a Moz2D DataSourceSurface.
* Marked as virtual so that browsercomps can access this method.
*/ */
mozilla::TemporaryRef<mozilla::gfx::DataSourceSurface> CopyToB8G8R8A8DataSourceSurface(); virtual mozilla::TemporaryRef<mozilla::gfx::DataSourceSurface> CopyToB8G8R8A8DataSourceSurface();
/* return new Subimage with pointing to original image starting from aRect.pos /* return new Subimage with pointing to original image starting from aRect.pos
* and size of aRect.size. New subimage keeping current image reference * and size of aRect.size. New subimage keeping current image reference