mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-14 22:13:31 +00:00
Bug 564388 - Make the 'quality' parameter to ToDataURL work for image/jpeg. Also fixes bug 401795 (handle excess arguments to ToDataURL by ignoring them). r=bz,roc
This commit is contained in:
parent
bc0a52beda
commit
ca7c39c21c
@ -123,7 +123,7 @@ var stringBundle;
|
|||||||
// and targets
|
// and targets
|
||||||
let io = Components.classes["@mozilla.org/network/io-service;1"].
|
let io = Components.classes["@mozilla.org/network/io-service;1"].
|
||||||
getService(Components.interfaces.nsIIOService);
|
getService(Components.interfaces.nsIIOService);
|
||||||
let source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
|
let source = io.newURI(canvas.toDataURL("image/png"), "UTF8", null);
|
||||||
let target = io.newFileURI(file);
|
let target = io.newFileURI(file);
|
||||||
|
|
||||||
// prepare to save the canvas data
|
// prepare to save the canvas data
|
||||||
|
@ -1558,6 +1558,6 @@ TabCanvas.prototype = {
|
|||||||
// ----------
|
// ----------
|
||||||
// Function: toImageData
|
// Function: toImageData
|
||||||
toImageData: function TabCanvas_toImageData() {
|
toImageData: function TabCanvas_toImageData() {
|
||||||
return this.canvas.toDataURL("image/png", "");
|
return this.canvas.toDataURL("image/png");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -80,6 +80,7 @@ _TEST_FILES_0 = \
|
|||||||
test_2d.composite.uncovered.image.source-in.html \
|
test_2d.composite.uncovered.image.source-in.html \
|
||||||
test_2d.composite.uncovered.image.source-out.html \
|
test_2d.composite.uncovered.image.source-out.html \
|
||||||
test_toDataURL_lowercase_ascii.html \
|
test_toDataURL_lowercase_ascii.html \
|
||||||
|
test_toDataURL_parameters.html \
|
||||||
test_mozGetAsFile.html \
|
test_mozGetAsFile.html \
|
||||||
test_canvas_strokeStyle_getter.html \
|
test_canvas_strokeStyle_getter.html \
|
||||||
test_bug613794.html \
|
test_bug613794.html \
|
||||||
|
@ -19537,21 +19537,23 @@ var canvas = document.getElementById('c614');
|
|||||||
var ctx = canvas.getContext('2d');
|
var ctx = canvas.getContext('2d');
|
||||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||||
|
|
||||||
|
var _threw = false;
|
||||||
try {
|
try {
|
||||||
var data = canvas.toDataURL('image/png', 'quality=100');
|
var data = canvas.toDataURL('image/png', 'quality=100');
|
||||||
ok(false, "Should have thrown an exception for invalid args to png encoder");
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
is(e.result, Components.results.NS_ERROR_INVALID_ARG, "Exception was wrong for png encoder");
|
_threw = true;
|
||||||
}
|
}
|
||||||
|
ok(!_threw, "Should not throw an exception for invalid args to png encoder");
|
||||||
|
|
||||||
|
_threw = false;
|
||||||
try {
|
try {
|
||||||
var data = canvas.toDataURL('image/jpeg', 'foobar=true');
|
var data = canvas.toDataURL('image/jpeg', 'foobar=true');
|
||||||
ok(false, "Should have thrown an exception for invalid args to jpeg encoder");
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
is(e.result, Components.results.NS_ERROR_INVALID_ARG, "Exception was wrong for jpeg encoder");
|
_threw = true;
|
||||||
}
|
}
|
||||||
|
ok(!_threw, "Should not throw an exception for invalid args to jpeg encoder");
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -20761,7 +20763,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -20788,7 +20790,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -20816,7 +20818,7 @@ ok(/^data:image\/png[;,]/.test(data), "data =~ /^data:image\\/png[;,]/");
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
_thrown_outer = true;
|
_thrown_outer = true;
|
||||||
}
|
}
|
||||||
todo(!_thrown_outer, 'should not throw exception');
|
ok(!_thrown_outer, 'should not throw exception');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
55
content/canvas/test/test_toDataURL_parameters.html
Normal file
55
content/canvas/test/test_toDataURL_parameters.html
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<title>Canvas test: toDataURL parameters (Bug 564388)</title>
|
||||||
|
<script src="/MochiKit/MochiKit.js"></script>
|
||||||
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
This test covers the JPEG quality parameter. If (when) the HTML5 spec changes the
|
||||||
|
allowed parameters for ToDataURL, new tests should go here.
|
||||||
|
</p>
|
||||||
|
<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
<script>
|
||||||
|
var canvas = document.getElementById('c');
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
ctx.strokeStyle = '#FF0000';
|
||||||
|
ctx.fillStyle = '#00FF00';
|
||||||
|
ctx.fillRect(0, 0, 100, 100);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(10, 10);
|
||||||
|
ctx.lineTo(90, 90);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
var pngData = canvas.toDataURL('image/png');
|
||||||
|
var pngQuality = canvas.toDataURL('image/png', 0.1);
|
||||||
|
is(pngQuality, pngData, "Quality is not supported for PNG images");
|
||||||
|
|
||||||
|
var data = canvas.toDataURL('image/jpeg');
|
||||||
|
if (data.match(/^data:image\/jpeg[;,]/)) {
|
||||||
|
// Test the JPEG quality parameter
|
||||||
|
|
||||||
|
var fullQuality = canvas.toDataURL('image/jpeg', 1.0);
|
||||||
|
var lowQuality = canvas.toDataURL('image/jpeg', 0.1);
|
||||||
|
isnot(lowQuality, fullQuality, "A low quality (0.1) should differ from high quality (1.0)");
|
||||||
|
|
||||||
|
var medQuality = canvas.toDataURL('image/jpeg', 0.5);
|
||||||
|
isnot(medQuality, fullQuality, "A medium quality (0.5) should differ from high (1.0)");
|
||||||
|
isnot(medQuality, lowQuality, "A medium quality (0.5) should differ from low (0.5)");
|
||||||
|
|
||||||
|
var tooHigh = canvas.toDataURL('image/jpeg', 2.0);
|
||||||
|
is(tooHigh, data, "Quality above 1.0 is treated as unspecified");
|
||||||
|
|
||||||
|
var tooLow = canvas.toDataURL('image/jpeg', -1.0);
|
||||||
|
is(tooLow, data, "Quality below 0.0 is treated as unspecified");
|
||||||
|
|
||||||
|
var lowQualityExtra = canvas.toDataURL('image/jpeg', 0.1, 'foo', 'bar', null);
|
||||||
|
is(lowQualityExtra, lowQuality, "Quality applies even if extra arguments are present");
|
||||||
|
|
||||||
|
var lowQualityUppercase = canvas.toDataURL('IMAGE/JPEG', 0.1);
|
||||||
|
is(lowQualityUppercase, lowQuality, "Quality applies to image/jpeg regardless of case");
|
||||||
|
|
||||||
|
var lowQualityString = canvas.toDataURL('image/jpeg', '0.1');
|
||||||
|
isnot(lowQualityString, lowQuality, "Quality must be a number (should not be a string)");
|
||||||
|
}
|
||||||
|
</script>
|
@ -181,7 +181,7 @@ protected:
|
|||||||
PRUint32& aSize,
|
PRUint32& aSize,
|
||||||
bool& aFellBackToPNG);
|
bool& aFellBackToPNG);
|
||||||
nsresult ToDataURLImpl(const nsAString& aMimeType,
|
nsresult ToDataURLImpl(const nsAString& aMimeType,
|
||||||
const nsAString& aEncoderOptions,
|
nsIVariant* aEncoderOptions,
|
||||||
nsAString& aDataURL);
|
nsAString& aDataURL);
|
||||||
nsresult MozGetAsFileImpl(const nsAString& aName,
|
nsresult MozGetAsFileImpl(const nsAString& aName,
|
||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
|
#include "nsMathUtils.h"
|
||||||
|
|
||||||
#include "nsFrameManager.h"
|
#include "nsFrameManager.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
@ -196,32 +197,17 @@ nsHTMLCanvasElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||||||
// nsHTMLCanvasElement::toDataURL
|
// nsHTMLCanvasElement::toDataURL
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLCanvasElement::ToDataURL(const nsAString& aType, const nsAString& aParams,
|
nsHTMLCanvasElement::ToDataURL(const nsAString& aType, nsIVariant* aParams,
|
||||||
PRUint8 optional_argc, nsAString& aDataURL)
|
PRUint8 optional_argc, nsAString& aDataURL)
|
||||||
{
|
{
|
||||||
// do a trust check if this is a write-only canvas
|
// do a trust check if this is a write-only canvas
|
||||||
// or if we're trying to use the 2-arg form
|
if (mWriteOnly && !nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
if ((mWriteOnly || optional_argc >= 2) &&
|
|
||||||
!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ToDataURLImpl(aType, aParams, aDataURL);
|
return ToDataURLImpl(aType, aParams, aDataURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// nsHTMLCanvasElement::toDataURLAs
|
|
||||||
//
|
|
||||||
// Native-callers only
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsHTMLCanvasElement::ToDataURLAs(const nsAString& aMimeType,
|
|
||||||
const nsAString& aEncoderOptions,
|
|
||||||
nsAString& aDataURL)
|
|
||||||
{
|
|
||||||
return ToDataURLImpl(aMimeType, aEncoderOptions, aDataURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLCanvasElement::ExtractData(const nsAString& aType,
|
nsHTMLCanvasElement::ExtractData(const nsAString& aType,
|
||||||
const nsAString& aOptions,
|
const nsAString& aOptions,
|
||||||
@ -323,7 +309,7 @@ nsHTMLCanvasElement::ExtractData(const nsAString& aType,
|
|||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
||||||
const nsAString& aEncoderOptions,
|
nsIVariant* aEncoderOptions,
|
||||||
nsAString& aDataURL)
|
nsAString& aDataURL)
|
||||||
{
|
{
|
||||||
bool fallbackToPNG = false;
|
bool fallbackToPNG = false;
|
||||||
@ -337,11 +323,30 @@ nsHTMLCanvasElement::ToDataURLImpl(const nsAString& aMimeType,
|
|||||||
nsAutoString type;
|
nsAutoString type;
|
||||||
nsContentUtils::ASCIIToLower(aMimeType, type);
|
nsContentUtils::ASCIIToLower(aMimeType, type);
|
||||||
|
|
||||||
|
nsAutoString params;
|
||||||
|
|
||||||
|
// Quality parameter is only valid for the image/jpeg MIME type
|
||||||
|
if (type.EqualsLiteral("image/jpeg")) {
|
||||||
|
PRUint16 vartype;
|
||||||
|
|
||||||
|
if (aEncoderOptions &&
|
||||||
|
NS_SUCCEEDED(aEncoderOptions->GetDataType(&vartype)) &&
|
||||||
|
vartype <= nsIDataType::VTYPE_DOUBLE) {
|
||||||
|
|
||||||
|
double quality;
|
||||||
|
// Quality must be between 0.0 and 1.0, inclusive
|
||||||
|
if (NS_SUCCEEDED(aEncoderOptions->GetAsDouble(&quality)) &&
|
||||||
|
quality >= 0.0 && quality <= 1.0) {
|
||||||
|
params.AppendLiteral("quality=");
|
||||||
|
params.AppendInt(NS_lround(quality * 100.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRUint32 imgSize = 0;
|
PRUint32 imgSize = 0;
|
||||||
char* imgData;
|
char* imgData;
|
||||||
|
|
||||||
nsresult rv = ExtractData(type, aEncoderOptions, imgData,
|
nsresult rv = ExtractData(type, params, imgData, imgSize, fallbackToPNG);
|
||||||
imgSize, fallbackToPNG);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// base 64, result will be NULL terminated
|
// base 64, result will be NULL terminated
|
||||||
|
@ -53,8 +53,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
interface nsIDOMFile;
|
interface nsIDOMFile;
|
||||||
|
interface nsIVariant;
|
||||||
|
|
||||||
[scriptable, uuid(2e98cd39-2269-493a-a3bb-abe85be2523c)]
|
[scriptable, uuid(010d8e6f-86ba-47ad-a04f-1a4d75f1caf8)]
|
||||||
interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
|
interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
|
||||||
{
|
{
|
||||||
attribute unsigned long width;
|
attribute unsigned long width;
|
||||||
@ -68,18 +69,10 @@ interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement
|
|||||||
// Valid calls are:
|
// Valid calls are:
|
||||||
// toDataURL(); -- defaults to image/png
|
// toDataURL(); -- defaults to image/png
|
||||||
// toDataURL(type); -- uses given type
|
// toDataURL(type); -- uses given type
|
||||||
// toDataURL(type, params); -- only available to trusted callers
|
// toDataURL(type, params); -- uses given type, and any valid parameters
|
||||||
[optional_argc] DOMString toDataURL([optional] in DOMString type,
|
[optional_argc] DOMString toDataURL([optional] in DOMString type,
|
||||||
[optional] in DOMString params);
|
[optional] in nsIVariant params);
|
||||||
|
|
||||||
// This version lets you specify different image types and pass parameters
|
|
||||||
// to the encoder. For example toDataURLAs("image/png", "transparency=none")
|
|
||||||
// gives you a PNG with the alpha channel discarded. See the encoder for
|
|
||||||
// the options string that it supports. Separate multiple options with
|
|
||||||
// semicolons.
|
|
||||||
[noscript] DOMString toDataURLAs(in DOMString mimeType, in DOMString encoderOptions);
|
|
||||||
|
|
||||||
|
|
||||||
// Valid calls are
|
// Valid calls are
|
||||||
// mozGetAsFile(name); -- defaults to image/png
|
// mozGetAsFile(name); -- defaults to image/png
|
||||||
// mozGetAsFile(name, type); -- uses given type
|
// mozGetAsFile(name, type); -- uses given type
|
||||||
|
Loading…
x
Reference in New Issue
Block a user