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

View File

@ -112,8 +112,9 @@ public:
/**
* 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
* and size of aRect.size. New subimage keeping current image reference