Loading content/canvas/public/nsICanvasRenderingContextInternal.h +5 −2 Original line number Diff line number Diff line Loading @@ -14,8 +14,8 @@ #include "mozilla/RefPtr.h" #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \ { 0x8b8da863, 0xd151, 0x4014, \ { 0x8b, 0xdc, 0x62, 0xb5, 0x0d, 0xc0, 0x2b, 0x62 } } { 0x9a6a5bdf, 0x1261, 0x4057, \ { 0x85, 0xcc, 0xaf, 0x97, 0x6c, 0x36, 0x99, 0xa9 } } class gfxContext; class gfxASurface; Loading Loading @@ -71,6 +71,9 @@ public: GraphicsFilter aFilter, uint32_t aFlags = RenderFlagPremultAlpha) = 0; // Creates an image buffer. Returns null on failure. virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) = 0; // Gives you a stream containing the image represented by this context. // The format is given in aMimeTime, for example "image/png". // Loading content/canvas/src/CanvasRenderingContext2D.cpp +43 −40 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ #include "nsTArray.h" #include "imgIEncoder.h" #include "ImageEncoder.h" #include "gfxContext.h" #include "gfxASurface.h" Loading Loading @@ -1052,71 +1052,71 @@ CanvasRenderingContext2D::Render(gfxContext *ctx, GraphicsFilter aFilter, uint32 return rv; } NS_IMETHODIMP CanvasRenderingContext2D::GetInputStream(const char *aMimeType, const PRUnichar *aEncoderOptions, nsIInputStream **aStream) void CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) { EnsureTarget(); if (!IsTargetValid()) { return NS_ERROR_FAILURE; } *aImageBuffer = nullptr; *aFormat = 0; nsRefPtr<gfxASurface> surface; if (NS_FAILED(GetThebesSurface(getter_AddRefs(surface)))) { return NS_ERROR_FAILURE; nsresult rv = GetThebesSurface(getter_AddRefs(surface)); if (NS_FAILED(rv)) { return; } nsresult rv; const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type="; static const fallible_t fallible = fallible_t(); nsAutoArrayPtr<char> conid(new (fallible) char[strlen(encoderPrefix) + strlen(aMimeType) + 1]); if (!conid) { return NS_ERROR_OUT_OF_MEMORY; } strcpy(conid, encoderPrefix); strcat(conid, aMimeType); nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid); if (!encoder) { return NS_ERROR_FAILURE; } nsAutoArrayPtr<uint8_t> imageBuffer(new (fallible) uint8_t[mWidth * mHeight * 4]); uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4]; if (!imageBuffer) { return NS_ERROR_OUT_OF_MEMORY; return; } nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(imageBuffer.get(), new gfxImageSurface(imageBuffer, gfxIntSize(mWidth, mHeight), mWidth * 4, gfxImageFormatARGB32); if (!imgsurf || imgsurf->CairoStatus()) { return NS_ERROR_FAILURE; delete[] imageBuffer; return; } nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf); if (!ctx || ctx->HasError()) { return NS_ERROR_FAILURE; delete[] imageBuffer; return; } ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(surface, gfxPoint(0, 0)); ctx->Paint(); rv = encoder->InitFromData(imageBuffer.get(), mWidth * mHeight * 4, mWidth, mHeight, mWidth * 4, imgIEncoder::INPUT_FORMAT_HOSTARGB, nsDependentString(aEncoderOptions)); NS_ENSURE_SUCCESS(rv, rv); *aImageBuffer = imageBuffer; *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB; } NS_IMETHODIMP CanvasRenderingContext2D::GetInputStream(const char *aMimeType, const PRUnichar *aEncoderOptions, nsIInputStream **aStream) { uint8_t* imageBuffer = nullptr; int32_t format = 0; GetImageBuffer(&imageBuffer, &format); if (!imageBuffer) { return NS_ERROR_FAILURE; } nsCString enccid("@mozilla.org/image/encoder;2?type="); enccid += aMimeType; nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get()); if (!encoder) { return NS_ERROR_FAILURE; } return CallQueryInterface(encoder, aStream); return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format, encoder, aEncoderOptions, aStream); } SurfaceFormat Loading Loading @@ -3817,6 +3817,9 @@ NS_IMETHODIMP CanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface) { EnsureTarget(); if (!IsTargetValid()) { return NS_ERROR_FAILURE; } nsRefPtr<gfxASurface> thebesSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget); Loading content/canvas/src/CanvasRenderingContext2D.h +3 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "mozilla/gfx/Rect.h" #include "mozilla/gfx/2D.h" #include "gfx2DGlue.h" #include "imgIEncoder.h" class nsXULElement; Loading Loading @@ -460,6 +461,8 @@ public: friend class CanvasRenderingContext2DUserData; virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat); protected: nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight, Loading content/canvas/src/Makefile.in +1 −0 Original line number Diff line number Diff line Loading @@ -22,5 +22,6 @@ INCLUDES += \ -I$(srcdir)/../../html/content/src \ -I$(srcdir)/../../../js/xpconnect/src \ -I$(srcdir)/../../../dom/base \ -I$(srcdir)/../../../image/src \ -I$(topsrcdir)/content/xul/content/src \ $(NULL) content/canvas/src/WebGLContext.cpp +58 −36 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ #include "nsIVariant.h" #include "imgIEncoder.h" #include "ImageEncoder.h" #include "gfxContext.h" #include "gfxPattern.h" Loading Loading @@ -735,57 +735,79 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded() } } NS_IMETHODIMP WebGLContext::GetInputStream(const char* aMimeType, const PRUnichar* aEncoderOptions, nsIInputStream **aStream) void WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) { NS_ASSERTION(gl, "GetInputStream on invalid context?"); if (!gl) return NS_ERROR_FAILURE; *aImageBuffer = nullptr; *aFormat = 0; nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight), nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(gfxIntSize(mWidth, mHeight), gfxImageFormatARGB32); if (surf->CairoStatus() != 0) return NS_ERROR_FAILURE; nsRefPtr<gfxContext> tmpcx = new gfxContext(surf); // Use Render() to make sure that appropriate y-flip gets applied uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0; nsresult rv = Render(tmpcx, GraphicsFilter::FILTER_NEAREST, flags); if (NS_FAILED(rv)) return rv; const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type="; nsAutoArrayPtr<char> conid(new char[strlen(encoderPrefix) + strlen(aMimeType) + 1]); if (!imgsurf || imgsurf->CairoStatus()) { return; } strcpy(conid, encoderPrefix); strcat(conid, aMimeType); nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf); if (!ctx || ctx->HasError()) { return; } nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid); if (!encoder) return NS_ERROR_FAILURE; // Use Render() to make sure that appropriate y-flip gets applied uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0; nsresult rv = Render(ctx, GraphicsFilter::FILTER_NEAREST, flags); if (NS_FAILED(rv)) { return; } int format = imgIEncoder::INPUT_FORMAT_HOSTARGB; int32_t format = imgIEncoder::INPUT_FORMAT_HOSTARGB; if (!mOptions.premultipliedAlpha) { // We need to convert to INPUT_FORMAT_RGBA, otherwise // we are automatically considered premult, and unpremult'd. // Yes, it is THAT silly. // Except for different lossy conversions by color, // we could probably just change the label, and not change the data. gfxUtils::ConvertBGRAtoRGBA(surf); gfxUtils::ConvertBGRAtoRGBA(imgsurf); format = imgIEncoder::INPUT_FORMAT_RGBA; } rv = encoder->InitFromData(surf->Data(), mWidth * mHeight * 4, mWidth, mHeight, surf->Stride(), format, nsDependentString(aEncoderOptions)); NS_ENSURE_SUCCESS(rv, rv); static const fallible_t fallible = fallible_t(); uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4]; if (!imageBuffer) { return; } memcpy(imageBuffer, imgsurf->Data(), mWidth * mHeight * 4); *aImageBuffer = imageBuffer; *aFormat = format; } NS_IMETHODIMP WebGLContext::GetInputStream(const char* aMimeType, const PRUnichar* aEncoderOptions, nsIInputStream **aStream) { NS_ASSERTION(gl, "GetInputStream on invalid context?"); if (!gl) return NS_ERROR_FAILURE; uint8_t* imageBuffer = nullptr; int32_t format = 0; GetImageBuffer(&imageBuffer, &format); if (!imageBuffer) { return NS_ERROR_FAILURE; } nsCString enccid("@mozilla.org/image/encoder;2?type="); enccid += aMimeType; nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get()); if (!encoder) { return NS_ERROR_FAILURE; } return CallQueryInterface(encoder, aStream); return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format, encoder, aEncoderOptions, aStream); } NS_IMETHODIMP Loading Loading
content/canvas/public/nsICanvasRenderingContextInternal.h +5 −2 Original line number Diff line number Diff line Loading @@ -14,8 +14,8 @@ #include "mozilla/RefPtr.h" #define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \ { 0x8b8da863, 0xd151, 0x4014, \ { 0x8b, 0xdc, 0x62, 0xb5, 0x0d, 0xc0, 0x2b, 0x62 } } { 0x9a6a5bdf, 0x1261, 0x4057, \ { 0x85, 0xcc, 0xaf, 0x97, 0x6c, 0x36, 0x99, 0xa9 } } class gfxContext; class gfxASurface; Loading Loading @@ -71,6 +71,9 @@ public: GraphicsFilter aFilter, uint32_t aFlags = RenderFlagPremultAlpha) = 0; // Creates an image buffer. Returns null on failure. virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) = 0; // Gives you a stream containing the image represented by this context. // The format is given in aMimeTime, for example "image/png". // Loading
content/canvas/src/CanvasRenderingContext2D.cpp +43 −40 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ #include "nsTArray.h" #include "imgIEncoder.h" #include "ImageEncoder.h" #include "gfxContext.h" #include "gfxASurface.h" Loading Loading @@ -1052,71 +1052,71 @@ CanvasRenderingContext2D::Render(gfxContext *ctx, GraphicsFilter aFilter, uint32 return rv; } NS_IMETHODIMP CanvasRenderingContext2D::GetInputStream(const char *aMimeType, const PRUnichar *aEncoderOptions, nsIInputStream **aStream) void CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) { EnsureTarget(); if (!IsTargetValid()) { return NS_ERROR_FAILURE; } *aImageBuffer = nullptr; *aFormat = 0; nsRefPtr<gfxASurface> surface; if (NS_FAILED(GetThebesSurface(getter_AddRefs(surface)))) { return NS_ERROR_FAILURE; nsresult rv = GetThebesSurface(getter_AddRefs(surface)); if (NS_FAILED(rv)) { return; } nsresult rv; const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type="; static const fallible_t fallible = fallible_t(); nsAutoArrayPtr<char> conid(new (fallible) char[strlen(encoderPrefix) + strlen(aMimeType) + 1]); if (!conid) { return NS_ERROR_OUT_OF_MEMORY; } strcpy(conid, encoderPrefix); strcat(conid, aMimeType); nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid); if (!encoder) { return NS_ERROR_FAILURE; } nsAutoArrayPtr<uint8_t> imageBuffer(new (fallible) uint8_t[mWidth * mHeight * 4]); uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4]; if (!imageBuffer) { return NS_ERROR_OUT_OF_MEMORY; return; } nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(imageBuffer.get(), new gfxImageSurface(imageBuffer, gfxIntSize(mWidth, mHeight), mWidth * 4, gfxImageFormatARGB32); if (!imgsurf || imgsurf->CairoStatus()) { return NS_ERROR_FAILURE; delete[] imageBuffer; return; } nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf); if (!ctx || ctx->HasError()) { return NS_ERROR_FAILURE; delete[] imageBuffer; return; } ctx->SetOperator(gfxContext::OPERATOR_SOURCE); ctx->SetSource(surface, gfxPoint(0, 0)); ctx->Paint(); rv = encoder->InitFromData(imageBuffer.get(), mWidth * mHeight * 4, mWidth, mHeight, mWidth * 4, imgIEncoder::INPUT_FORMAT_HOSTARGB, nsDependentString(aEncoderOptions)); NS_ENSURE_SUCCESS(rv, rv); *aImageBuffer = imageBuffer; *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB; } NS_IMETHODIMP CanvasRenderingContext2D::GetInputStream(const char *aMimeType, const PRUnichar *aEncoderOptions, nsIInputStream **aStream) { uint8_t* imageBuffer = nullptr; int32_t format = 0; GetImageBuffer(&imageBuffer, &format); if (!imageBuffer) { return NS_ERROR_FAILURE; } nsCString enccid("@mozilla.org/image/encoder;2?type="); enccid += aMimeType; nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get()); if (!encoder) { return NS_ERROR_FAILURE; } return CallQueryInterface(encoder, aStream); return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format, encoder, aEncoderOptions, aStream); } SurfaceFormat Loading Loading @@ -3817,6 +3817,9 @@ NS_IMETHODIMP CanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface) { EnsureTarget(); if (!IsTargetValid()) { return NS_ERROR_FAILURE; } nsRefPtr<gfxASurface> thebesSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget); Loading
content/canvas/src/CanvasRenderingContext2D.h +3 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "mozilla/gfx/Rect.h" #include "mozilla/gfx/2D.h" #include "gfx2DGlue.h" #include "imgIEncoder.h" class nsXULElement; Loading Loading @@ -460,6 +461,8 @@ public: friend class CanvasRenderingContext2DUserData; virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat); protected: nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight, Loading
content/canvas/src/Makefile.in +1 −0 Original line number Diff line number Diff line Loading @@ -22,5 +22,6 @@ INCLUDES += \ -I$(srcdir)/../../html/content/src \ -I$(srcdir)/../../../js/xpconnect/src \ -I$(srcdir)/../../../dom/base \ -I$(srcdir)/../../../image/src \ -I$(topsrcdir)/content/xul/content/src \ $(NULL)
content/canvas/src/WebGLContext.cpp +58 −36 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ #include "nsIVariant.h" #include "imgIEncoder.h" #include "ImageEncoder.h" #include "gfxContext.h" #include "gfxPattern.h" Loading Loading @@ -735,57 +735,79 @@ void WebGLContext::LoseOldestWebGLContextIfLimitExceeded() } } NS_IMETHODIMP WebGLContext::GetInputStream(const char* aMimeType, const PRUnichar* aEncoderOptions, nsIInputStream **aStream) void WebGLContext::GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) { NS_ASSERTION(gl, "GetInputStream on invalid context?"); if (!gl) return NS_ERROR_FAILURE; *aImageBuffer = nullptr; *aFormat = 0; nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight), nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(gfxIntSize(mWidth, mHeight), gfxImageFormatARGB32); if (surf->CairoStatus() != 0) return NS_ERROR_FAILURE; nsRefPtr<gfxContext> tmpcx = new gfxContext(surf); // Use Render() to make sure that appropriate y-flip gets applied uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0; nsresult rv = Render(tmpcx, GraphicsFilter::FILTER_NEAREST, flags); if (NS_FAILED(rv)) return rv; const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type="; nsAutoArrayPtr<char> conid(new char[strlen(encoderPrefix) + strlen(aMimeType) + 1]); if (!imgsurf || imgsurf->CairoStatus()) { return; } strcpy(conid, encoderPrefix); strcat(conid, aMimeType); nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf); if (!ctx || ctx->HasError()) { return; } nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(conid); if (!encoder) return NS_ERROR_FAILURE; // Use Render() to make sure that appropriate y-flip gets applied uint32_t flags = mOptions.premultipliedAlpha ? RenderFlagPremultAlpha : 0; nsresult rv = Render(ctx, GraphicsFilter::FILTER_NEAREST, flags); if (NS_FAILED(rv)) { return; } int format = imgIEncoder::INPUT_FORMAT_HOSTARGB; int32_t format = imgIEncoder::INPUT_FORMAT_HOSTARGB; if (!mOptions.premultipliedAlpha) { // We need to convert to INPUT_FORMAT_RGBA, otherwise // we are automatically considered premult, and unpremult'd. // Yes, it is THAT silly. // Except for different lossy conversions by color, // we could probably just change the label, and not change the data. gfxUtils::ConvertBGRAtoRGBA(surf); gfxUtils::ConvertBGRAtoRGBA(imgsurf); format = imgIEncoder::INPUT_FORMAT_RGBA; } rv = encoder->InitFromData(surf->Data(), mWidth * mHeight * 4, mWidth, mHeight, surf->Stride(), format, nsDependentString(aEncoderOptions)); NS_ENSURE_SUCCESS(rv, rv); static const fallible_t fallible = fallible_t(); uint8_t* imageBuffer = new (fallible) uint8_t[mWidth * mHeight * 4]; if (!imageBuffer) { return; } memcpy(imageBuffer, imgsurf->Data(), mWidth * mHeight * 4); *aImageBuffer = imageBuffer; *aFormat = format; } NS_IMETHODIMP WebGLContext::GetInputStream(const char* aMimeType, const PRUnichar* aEncoderOptions, nsIInputStream **aStream) { NS_ASSERTION(gl, "GetInputStream on invalid context?"); if (!gl) return NS_ERROR_FAILURE; uint8_t* imageBuffer = nullptr; int32_t format = 0; GetImageBuffer(&imageBuffer, &format); if (!imageBuffer) { return NS_ERROR_FAILURE; } nsCString enccid("@mozilla.org/image/encoder;2?type="); enccid += aMimeType; nsCOMPtr<imgIEncoder> encoder = do_CreateInstance(enccid.get()); if (!encoder) { return NS_ERROR_FAILURE; } return CallQueryInterface(encoder, aStream); return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format, encoder, aEncoderOptions, aStream); } NS_IMETHODIMP Loading