diff --git a/.eslintrc.js b/.eslintrc.js index 034eac6a0c29..4226cea54feb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -45,7 +45,6 @@ module.exports = { "overrides": [{ "files": [ "devtools/**", - "image/**", "intl/**", "ipc/**", "js/**", diff --git a/.prettierignore b/.prettierignore index a3e92b9a05e3..ec6bdb6448b9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js toolkit/components/telemetry/healthreport-prefs.js # Ignore all top-level directories for now. -image/** intl/** ipc/** js/** diff --git a/image/test/browser/browser_bug666317.js b/image/test/browser/browser_bug666317.js index 3c1942002924..e2934f2ffb75 100644 --- a/image/test/browser/browser_bug666317.js +++ b/image/test/browser/browser_bug666317.js @@ -1,14 +1,16 @@ waitForExplicitFinish(); var pageSource = - '' + - '' + - ''; + "" + + '' + + ""; var oldDiscardingPref, oldTab, newTab; var prefBranch = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService) - .getBranch('image.mem.'); + .getService(Ci.nsIPrefService) + .getBranch("image.mem."); var gWaitingForDiscard = false; var gScriptedObserver; @@ -17,81 +19,83 @@ var gClonedRequest; function ImageObserver(decodeCallback, discardCallback) { this.decodeComplete = function onDecodeComplete(aRequest) { decodeCallback(); - } + }; - this.discard = function onDiscard(request) - { + this.discard = function onDiscard(request) { if (!gWaitingForDiscard) { return; } this.synchronous = false; discardCallback(); - } + }; this.synchronous = true; } function currentRequest() { - let img = gBrowser.getBrowserForTab(newTab).contentWindow - .document.getElementById('testImg'); + let img = gBrowser + .getBrowserForTab(newTab) + .contentWindow.document.getElementById("testImg"); return img.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST); } function isImgDecoded() { let request = currentRequest(); - return request.imageStatus & Ci.imgIRequest.STATUS_DECODE_COMPLETE ? true : false; + return request.imageStatus & Ci.imgIRequest.STATUS_DECODE_COMPLETE + ? true + : false; } // Ensure that the image is decoded by drawing it to a canvas. function forceDecodeImg() { let doc = gBrowser.getBrowserForTab(newTab).contentWindow.document; - let img = doc.getElementById('testImg'); - let canvas = doc.createElement('canvas'); - let ctx = canvas.getContext('2d'); + let img = doc.getElementById("testImg"); + let canvas = doc.createElement("canvas"); + let ctx = canvas.getContext("2d"); ctx.drawImage(img, 0, 0); } function runAfterAsyncEvents(aCallback) { function handlePostMessage(aEvent) { - if (aEvent.data == 'next') { - window.removeEventListener('message', handlePostMessage); + if (aEvent.data == "next") { + window.removeEventListener("message", handlePostMessage); aCallback(); } } - window.addEventListener('message', handlePostMessage); + window.addEventListener("message", handlePostMessage); // We'll receive the 'message' event after everything else that's currently in // the event queue (which is a stronger guarantee than setTimeout, because // setTimeout events may be coalesced). This lets us ensure that we run // aCallback *after* any asynchronous events are delivered. - window.postMessage('next', '*'); + window.postMessage("next", "*"); } function test() { // Enable the discarding pref. - oldDiscardingPref = prefBranch.getBoolPref('discardable'); - prefBranch.setBoolPref('discardable', true); + oldDiscardingPref = prefBranch.getBoolPref("discardable"); + prefBranch.setBoolPref("discardable", true); // Create and focus a new tab. oldTab = gBrowser.selectedTab; - newTab = BrowserTestUtils.addTab(gBrowser, 'data:text/html,' + pageSource); + newTab = BrowserTestUtils.addTab(gBrowser, "data:text/html," + pageSource); gBrowser.selectedTab = newTab; // Run step2 after the tab loads. - gBrowser.getBrowserForTab(newTab) - .addEventListener("pageshow", step2); + gBrowser.getBrowserForTab(newTab).addEventListener("pageshow", step2); } function step2() { // Create the image observer. - var observer = - new ImageObserver(() => runAfterAsyncEvents(step3), // DECODE_COMPLETE - () => runAfterAsyncEvents(step5)); // DISCARD + var observer = new ImageObserver( + () => runAfterAsyncEvents(step3), // DECODE_COMPLETE + () => runAfterAsyncEvents(step5) + ); // DISCARD gScriptedObserver = Cc["@mozilla.org/image/tools;1"] - .getService(Ci.imgITools) - .createScriptedObserver(observer); + .getService(Ci.imgITools) + .createScriptedObserver(observer); // Clone the current imgIRequest with our new observer. var request = currentRequest(); @@ -105,7 +109,7 @@ function step2() { } function step3() { - ok(isImgDecoded(), 'Image should initially be decoded.'); + ok(isImgDecoded(), "Image should initially be decoded."); // Focus the old tab, then fire a memory-pressure notification. This should // cause the decoded image in the new tab to be discarded. @@ -118,20 +122,21 @@ function step3() { function step4() { gWaitingForDiscard = true; - var os = Cc["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - os.notifyObservers(null, 'memory-pressure', 'heap-minimize'); + var os = Cc["@mozilla.org/observer-service;1"].getService( + Ci.nsIObserverService + ); + os.notifyObservers(null, "memory-pressure", "heap-minimize"); // The DISCARD notification is delivered asynchronously. ImageObserver will // eventually call step5. (Or else, sadly, the test will time out.) } function step5() { - ok(true, 'Image should be discarded.'); + ok(true, "Image should be discarded."); // And we're done. gBrowser.removeTab(newTab); - prefBranch.setBoolPref('discardable', oldDiscardingPref); + prefBranch.setBoolPref("discardable", oldDiscardingPref); gClonedRequest.cancelAndForgetObserver(0); diff --git a/image/test/browser/browser_docshell_type_editor.js b/image/test/browser/browser_docshell_type_editor.js index 959929ef3403..42d63f6838f8 100644 --- a/image/test/browser/browser_docshell_type_editor.js +++ b/image/test/browser/browser_docshell_type_editor.js @@ -1,4 +1,3 @@ - "use strict"; const SIMPLE_HTML = "data:text/html,"; @@ -10,8 +9,7 @@ const SIMPLE_HTML = "data:text/html,"; */ function getManifestDir() { let path = getTestFilePath("browser_docshell_type_editor"); - let file = Cc["@mozilla.org/file/local;1"] - .createInstance(Ci.nsIFile); + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); return file; } @@ -28,92 +26,111 @@ add_task(async function() { let manifestDir = getManifestDir(); Components.manager.addBootstrappedManifestLocation(manifestDir); - await BrowserTestUtils.withNewTab({ - gBrowser, - url: SIMPLE_HTML - }, async function(browser) { - await ContentTask.spawn(browser, null, async function() { - let rootDocShell = docShell.QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDocShell); - let defaultAppType = rootDocShell.appType; + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: SIMPLE_HTML, + }, + async function(browser) { + await ContentTask.spawn(browser, null, async function() { + let rootDocShell = docShell + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell); + let defaultAppType = rootDocShell.appType; - rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_EDITOR; + rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_EDITOR; - is(rootDocShell.appType, Ci.nsIDocShell.APP_TYPE_EDITOR, - "sanity check: appType after update should be type editor"); + is( + rootDocShell.appType, + Ci.nsIDocShell.APP_TYPE_EDITOR, + "sanity check: appType after update should be type editor" + ); - - return new Promise(resolve => { - let doc = content.document; - let image = doc.createElement("img"); - image.onload = function() { - ok(true, "APP_TYPE_EDITOR is allowed to load privileged image"); - // restore appType of rootDocShell before moving on to the next test - rootDocShell.appType = defaultAppType; - resolve(); - } - image.onerror = function() { - ok(false, "APP_TYPE_EDITOR is allowed to load privileged image"); - // restore appType of rootDocShell before moving on to the next test - rootDocShell.appType = defaultAppType; - resolve(); - } - doc.body.appendChild(image); - image.src = "chrome://test1/skin/privileged.png"; + return new Promise(resolve => { + let doc = content.document; + let image = doc.createElement("img"); + image.onload = function() { + ok(true, "APP_TYPE_EDITOR is allowed to load privileged image"); + // restore appType of rootDocShell before moving on to the next test + rootDocShell.appType = defaultAppType; + resolve(); + }; + image.onerror = function() { + ok(false, "APP_TYPE_EDITOR is allowed to load privileged image"); + // restore appType of rootDocShell before moving on to the next test + rootDocShell.appType = defaultAppType; + resolve(); + }; + doc.body.appendChild(image); + image.src = "chrome://test1/skin/privileged.png"; + }); }); - }); - }); + } + ); Components.manager.removeBootstrappedManifestLocation(manifestDir); }); add_task(async function() { - info("docshell of appType APP_TYPE_UNKNOWN can *not* access privileged images."); + info( + "docshell of appType APP_TYPE_UNKNOWN can *not* access privileged images." + ); // Load a temporary manifest adding a route to a privileged image let manifestDir = getManifestDir(); Components.manager.addBootstrappedManifestLocation(manifestDir); - await BrowserTestUtils.withNewTab({ - gBrowser, - url: SIMPLE_HTML - }, async function(browser) { - await ContentTask.spawn(browser, null, async function() { - let rootDocShell = docShell.QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDocShell); - let defaultAppType = rootDocShell.appType; + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: SIMPLE_HTML, + }, + async function(browser) { + await ContentTask.spawn(browser, null, async function() { + let rootDocShell = docShell + .QueryInterface(Ci.nsIDocShellTreeItem) + .rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell); + let defaultAppType = rootDocShell.appType; - rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_UNKNOWN; + rootDocShell.appType = Ci.nsIDocShell.APP_TYPE_UNKNOWN; - is(rootDocShell.appType, Ci.nsIDocShell.APP_TYPE_UNKNOWN, - "sanity check: appType of docshell should be unknown"); + is( + rootDocShell.appType, + Ci.nsIDocShell.APP_TYPE_UNKNOWN, + "sanity check: appType of docshell should be unknown" + ); - return new Promise(resolve => { - let doc = content.document; - let image = doc.createElement("img"); - image.onload = function() { - ok(false, "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image"); - // restore appType of rootDocShell before moving on to the next test - rootDocShell.appType = defaultAppType; - resolve(); - } - image.onerror = function() { - ok(true, "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image"); - // restore appType of rootDocShell before moving on to the next test - rootDocShell.appType = defaultAppType; - resolve(); - } - doc.body.appendChild(image); - // Set the src via wrappedJSObject so the load is triggered with - // the content page's principal rather than ours. - image.wrappedJSObject.src = "chrome://test1/skin/privileged.png"; + return new Promise(resolve => { + let doc = content.document; + let image = doc.createElement("img"); + image.onload = function() { + ok( + false, + "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image" + ); + // restore appType of rootDocShell before moving on to the next test + rootDocShell.appType = defaultAppType; + resolve(); + }; + image.onerror = function() { + ok( + true, + "APP_TYPE_UNKNOWN is *not* allowed to acces privileged image" + ); + // restore appType of rootDocShell before moving on to the next test + rootDocShell.appType = defaultAppType; + resolve(); + }; + doc.body.appendChild(image); + // Set the src via wrappedJSObject so the load is triggered with + // the content page's principal rather than ours. + image.wrappedJSObject.src = "chrome://test1/skin/privileged.png"; + }); }); - }); - }); + } + ); Components.manager.removeBootstrappedManifestLocation(manifestDir); }); diff --git a/image/test/browser/browser_image.js b/image/test/browser/browser_image.js index e467232319be..297a9922fa57 100644 --- a/image/test/browser/browser_image.js +++ b/image/test/browser/browser_image.js @@ -11,20 +11,29 @@ function testBFCache() { function theTest() { var abort = false; var chances, gImage, gFrames; - gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "image.html"); - gBrowser.selectedBrowser.addEventListener("pageshow", function () { - var window = gBrowser.contentWindow; - // If false, we are in an optimized build, and we abort this and - // all further tests - if (!actOnMozImage(window.document, "img1", function(image) { - gImage = image; - gFrames = gImage.framesNotified; - })) { - gBrowser.removeCurrentTab(); - abort = true; - } - goer.next(); - }, {capture: true, once: true}); + gBrowser.selectedTab = BrowserTestUtils.addTab( + gBrowser, + TESTROOT + "image.html" + ); + gBrowser.selectedBrowser.addEventListener( + "pageshow", + function() { + var window = gBrowser.contentWindow; + // If false, we are in an optimized build, and we abort this and + // all further tests + if ( + !actOnMozImage(window.document, "img1", function(image) { + gImage = image; + gFrames = gImage.framesNotified; + }) + ) { + gBrowser.removeCurrentTab(); + abort = true; + } + goer.next(); + }, + { capture: true, once: true } + ); yield; if (abort) { finish(); @@ -35,15 +44,19 @@ function testBFCache() { chances = 120; do { gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - gTimer.initWithCallback(function() { - if (gImage.framesNotified >= 20) { - goer.send(true); - } else { - chances--; - goer.send(chances == 0); // maybe if we wait a bit, it will happen - } - }, 500, Ci.nsITimer.TYPE_ONE_SHOT); - } while (!(yield)); + gTimer.initWithCallback( + function() { + if (gImage.framesNotified >= 20) { + goer.send(true); + } else { + chances--; + goer.send(chances == 0); // maybe if we wait a bit, it will happen + } + }, + 500, + Ci.nsITimer.TYPE_ONE_SHOT + ); + } while (!yield); is(chances > 0, true, "Must have animated a few frames so far"); // Browse elsewhere; push our animating page into the bfcache @@ -52,16 +65,30 @@ function testBFCache() { // Wait a bit for page to fully load, then wait a while and // see that no animation occurs. gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - gTimer.initWithCallback(function() { - gFrames = gImage.framesNotified; - gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - gTimer.initWithCallback(function() { - // Might have a few stray frames, until other page totally loads - var additionalFrames = gImage.framesNotified - gFrames; - is(additionalFrames == 0, true, "Must have not animated in bfcache! Got " + additionalFrames + " additional frames"); - goer.next(); - }, 4000, Ci.nsITimer.TYPE_ONE_SHOT); // 4 seconds - expect 40 frames - }, 0, Ci.nsITimer.TYPE_ONE_SHOT); // delay of 0 - wait for next event loop + gTimer.initWithCallback( + function() { + gFrames = gImage.framesNotified; + gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + gTimer.initWithCallback( + function() { + // Might have a few stray frames, until other page totally loads + var additionalFrames = gImage.framesNotified - gFrames; + is( + additionalFrames == 0, + true, + "Must have not animated in bfcache! Got " + + additionalFrames + + " additional frames" + ); + goer.next(); + }, + 4000, + Ci.nsITimer.TYPE_ONE_SHOT + ); // 4 seconds - expect 40 frames + }, + 0, + Ci.nsITimer.TYPE_ONE_SHOT + ); // delay of 0 - wait for next event loop yield; // Go back @@ -70,15 +97,19 @@ function testBFCache() { chances = 120; do { gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - gTimer.initWithCallback(function() { - if (gImage.framesNotified - gFrames >= 20) { - goer.send(true); - } else { - chances--; - goer.send(chances == 0); // maybe if we wait a bit, it will happen - } - }, 500, Ci.nsITimer.TYPE_ONE_SHOT); - } while (!(yield)); + gTimer.initWithCallback( + function() { + if (gImage.framesNotified - gFrames >= 20) { + goer.send(true); + } else { + chances--; + goer.send(chances == 0); // maybe if we wait a bit, it will happen + } + }, + 500, + Ci.nsITimer.TYPE_ONE_SHOT + ); + } while (!yield); is(chances > 0, true, "Must have animated once out of bfcache!"); // Finally, check that the css background image has essentially the same @@ -90,9 +121,17 @@ function testBFCache() { var div = doc.getElementById("background_div"); div.innerHTML += ''; actOnMozImage(doc, "img3", function(image) { - is(Math.abs(image.framesNotified - gImage.framesNotified)/gImage.framesNotified < 0.5, true, - "Must have also animated the background image, and essentially the same # of frames. " + - "Regular image got " + gImage.framesNotified + " frames but background image got " + image.framesNotified); + is( + Math.abs(image.framesNotified - gImage.framesNotified) / + gImage.framesNotified < + 0.5, + true, + "Must have also animated the background image, and essentially the same # of frames. " + + "Regular image got " + + gImage.framesNotified + + " frames but background image got " + + image.framesNotified + ); }); gBrowser.removeCurrentTab(); @@ -111,57 +150,87 @@ function testSharedContainers() { var gImages = []; var gFrames; - gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "image.html"); - gBrowser.selectedBrowser.addEventListener("pageshow", function () { - actOnMozImage(gBrowser.contentDocument, "img1", function(image) { - gImages[0] = image; - gFrames = image.framesNotified; // May in theory have frames from last test - // in this counter - so subtract them out - }); - goer.next(); - }, {capture: true, once: true}); + gBrowser.selectedTab = BrowserTestUtils.addTab( + gBrowser, + TESTROOT + "image.html" + ); + gBrowser.selectedBrowser.addEventListener( + "pageshow", + function() { + actOnMozImage(gBrowser.contentDocument, "img1", function(image) { + gImages[0] = image; + gFrames = image.framesNotified; // May in theory have frames from last test + // in this counter - so subtract them out + }); + goer.next(); + }, + { capture: true, once: true } + ); yield; // Load next tab somewhat later gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - gTimer.initWithCallback(function() { - goer.next(); - }, 1500, Ci.nsITimer.TYPE_ONE_SHOT); + gTimer.initWithCallback( + function() { + goer.next(); + }, + 1500, + Ci.nsITimer.TYPE_ONE_SHOT + ); yield; - gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "imageX2.html"); - gBrowser.selectedBrowser.addEventListener("pageshow", function () { - [1,2].forEach(function(i) { - actOnMozImage(gBrowser.contentDocument, "img"+i, function(image) { - gImages[i] = image; + gBrowser.selectedTab = BrowserTestUtils.addTab( + gBrowser, + TESTROOT + "imageX2.html" + ); + gBrowser.selectedBrowser.addEventListener( + "pageshow", + function() { + [1, 2].forEach(function(i) { + actOnMozImage(gBrowser.contentDocument, "img" + i, function(image) { + gImages[i] = image; + }); }); - }); - goer.next(); - }, {capture: true, once: true}); + goer.next(); + }, + { capture: true, once: true } + ); yield; var chances = 120; do { gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - gTimer.initWithCallback(function() { - if (gImages[0].framesNotified - gFrames >= 10) { - goer.send(true); - } else { - chances--; - goer.send(chances == 0); // maybe if we wait a bit, it will happen - } - }, 500, Ci.nsITimer.TYPE_ONE_SHOT); - } while (!(yield)); - is(chances > 0, true, "Must have been animating while showing several images"); + gTimer.initWithCallback( + function() { + if (gImages[0].framesNotified - gFrames >= 10) { + goer.send(true); + } else { + chances--; + goer.send(chances == 0); // maybe if we wait a bit, it will happen + } + }, + 500, + Ci.nsITimer.TYPE_ONE_SHOT + ); + } while (!yield); + is( + chances > 0, + true, + "Must have been animating while showing several images" + ); // Check they all have the same frame counts var theFrames = null; - [0,1,2].forEach(function(i) { + [0, 1, 2].forEach(function(i) { var frames = gImages[i].framesNotified; if (theFrames == null) { theFrames = frames; } else { - is(theFrames, frames, "Sharing the same imgContainer means *exactly* the same frame counts!"); + is( + theFrames, + frames, + "Sharing the same imgContainer means *exactly* the same frame counts!" + ); } }); @@ -189,4 +258,3 @@ function test() { ignoreAllUncaughtExceptions(); nextTest(); } - diff --git a/image/test/browser/head.js b/image/test/browser/head.js index 08ec12bbc62f..020c8bd35f6c 100644 --- a/image/test/browser/head.js +++ b/image/test/browser/head.js @@ -12,12 +12,13 @@ function getImageLoading(doc, id) { // Tries to get the Moz debug image, imgIContainerDebug. Only works // in a debug build. If we succeed, we call func(). function actOnMozImage(doc, id, func) { - var imgContainer = getImageLoading(doc, id).getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST).image; + var imgContainer = getImageLoading(doc, id).getRequest( + Ci.nsIImageLoadingContent.CURRENT_REQUEST + ).image; var mozImage; try { mozImage = imgContainer.QueryInterface(Ci.imgIContainerDebug); - } - catch (e) { + } catch (e) { return false; } func(mozImage); diff --git a/image/test/mochitest/animationPolling.js b/image/test/mochitest/animationPolling.js index c4ad8c0959e4..2cf3428166e5 100644 --- a/image/test/mochitest/animationPolling.js +++ b/image/test/mochitest/animationPolling.js @@ -3,49 +3,56 @@ var currentTest; var gIsRefImageLoaded = false; const gShouldOutputDebugInfo = false; -function pollForSuccess() -{ +function pollForSuccess() { if (!currentTest.isTestFinished) { - if (!currentTest.reusingReferenceImage || (currentTest.reusingReferenceImage - && gRefImageLoaded)) { + if ( + !currentTest.reusingReferenceImage || + (currentTest.reusingReferenceImage && gRefImageLoaded) + ) { currentTest.checkImage(); } setTimeout(pollForSuccess, currentTest.pollFreq); } -}; +} -function referencePoller() -{ +function referencePoller() { currentTest.takeReferenceSnapshot(); } -function reuseImageCallback() -{ +function reuseImageCallback() { gIsRefImageLoaded = true; } -function failTest() -{ +function failTest() { if (currentTest.isTestFinished || currentTest.closeFunc) { return; } - ok(false, "timing out after " + currentTest.timeout + "ms. " - + "Animated image still doesn't look correct, after poll #" - + currentTest.pollCounter); + ok( + false, + "timing out after " + + currentTest.timeout + + "ms. " + + "Animated image still doesn't look correct, after poll #" + + currentTest.pollCounter + ); currentTest.wereFailures = true; if (currentTest.currentSnapshotDataURI) { - currentTest.outputDebugInfo("Snapshot #" + currentTest.pollCounter, - "snapNum" + currentTest.pollCounter, - currentTest.currentSnapshotDataURI); + currentTest.outputDebugInfo( + "Snapshot #" + currentTest.pollCounter, + "snapNum" + currentTest.pollCounter, + currentTest.currentSnapshotDataURI + ); } - currentTest.enableDisplay(document.getElementById(currentTest.debugElementId)); + currentTest.enableDisplay( + document.getElementById(currentTest.debugElementId) + ); currentTest.cleanUpAndFinish(); -}; +} /** * Create a new AnimationTest object. @@ -75,9 +82,17 @@ function failTest() * chain tests together, so they are all finished exactly once. * @returns {AnimationTest} */ -function AnimationTest(pollFreq, timeout, referenceElementId, imageElementId, - debugElementId, cleanId, srcAttr, xulTest, closeFunc) -{ +function AnimationTest( + pollFreq, + timeout, + referenceElementId, + imageElementId, + debugElementId, + cleanId, + srcAttr, + xulTest, + closeFunc +) { // We want to test the cold loading behavior, so clear cache in case an // earlier test got our image in there already. clearAllImageCaches(); @@ -103,24 +118,24 @@ function AnimationTest(pollFreq, timeout, referenceElementId, imageElementId, this.numRefsTaken = 0; this.blankWaitTime = 0; - this.cleanId = cleanId ? cleanId : ''; - this.xulTest = xulTest ? xulTest : ''; - this.closeFunc = closeFunc ? closeFunc : ''; -}; + this.cleanId = cleanId ? cleanId : ""; + this.xulTest = xulTest ? xulTest : ""; + this.closeFunc = closeFunc ? closeFunc : ""; +} -AnimationTest.prototype.preloadImage = function() -{ +AnimationTest.prototype.preloadImage = function() { if (this.srcAttr) { this.myImage = new Image(); - this.myImage.onload = function() { currentTest.continueTest(); }; + this.myImage.onload = function() { + currentTest.continueTest(); + }; this.myImage.src = this.srcAttr; } else { this.continueTest(); } }; -AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri) -{ +AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri) { if (!gShouldOutputDebugInfo) { return; } @@ -135,13 +150,11 @@ AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri) todo(false, "Debug (" + id + "): " + message + " " + dataUri); }; -AnimationTest.prototype.isFinished = function() -{ +AnimationTest.prototype.isFinished = function() { return this.isTestFinished; }; -AnimationTest.prototype.takeCleanSnapshot = function() -{ +AnimationTest.prototype.takeCleanSnapshot = function() { var cleanElement; if (this.cleanId) { cleanElement = document.getElementById(this.cleanId); @@ -161,18 +174,23 @@ AnimationTest.prototype.takeCleanSnapshot = function() } var dataString1 = "Clean Snapshot"; - this.outputDebugInfo(dataString1, 'cleanSnap', - this.cleanSnapshot.toDataURL()); + this.outputDebugInfo( + dataString1, + "cleanSnap", + this.cleanSnapshot.toDataURL() + ); }; -AnimationTest.prototype.takeBlankSnapshot = function() -{ +AnimationTest.prototype.takeBlankSnapshot = function() { // Take a snapshot of the initial (essentially blank) page this.blankSnapshot = snapshotWindow(window, false); var dataString1 = "Initial Blank Snapshot"; - this.outputDebugInfo(dataString1, 'blank1Snap', - this.blankSnapshot.toDataURL()); + this.outputDebugInfo( + dataString1, + "blank1Snap", + this.blankSnapshot.toDataURL() + ); }; /** @@ -182,8 +200,7 @@ AnimationTest.prototype.takeBlankSnapshot = function() * image, if applicable, and then asynchronously call continueTest(), or if not * applicable, synchronously trigger a call to continueTest(). */ -AnimationTest.prototype.beginTest = function() -{ +AnimationTest.prototype.beginTest = function() { SimpleTest.waitForExplicitFinish(); SimpleTest.requestFlakyTimeout("untriaged"); @@ -196,8 +213,7 @@ AnimationTest.prototype.beginTest = function() * beginTest() either synchronously or asynchronously, as an image load * callback. */ -AnimationTest.prototype.continueTest = function() -{ +AnimationTest.prototype.continueTest = function() { // In case something goes wrong, fail earlier than mochitest timeout, // and with more information. setTimeout(failTest, this.timeout); @@ -211,34 +227,35 @@ AnimationTest.prototype.continueTest = function() SimpleTest.executeSoon(pollForSuccess); }; -AnimationTest.prototype.setupPolledImage = function () -{ +AnimationTest.prototype.setupPolledImage = function() { // Make sure the image is visible if (!this.reusingImageAsReference) { this.enableDisplay(document.getElementById(this.imageElementId)); var currentSnapshot = snapshotWindow(window, false); - var result = compareSnapshots(currentSnapshot, - this.referenceSnapshot, true); + var result = compareSnapshots( + currentSnapshot, + this.referenceSnapshot, + true + ); this.currentSnapshotDataURI = currentSnapshot.toDataURL(); if (result[0]) { // SUCCESS! - ok(true, "Animated image looks correct, at poll #" - + this.pollCounter); + ok(true, "Animated image looks correct, at poll #" + this.pollCounter); this.cleanUpAndFinish(); } } else if (!gIsRefImageLoaded) { - this.myImage = new Image(); - this.myImage.onload = reuseImageCallback; - document.getElementById(this.imageElementId).setAttribute('src', - this.referenceElementId); - } -} + this.myImage = new Image(); + this.myImage.onload = reuseImageCallback; + document + .getElementById(this.imageElementId) + .setAttribute("src", this.referenceElementId); + } +}; -AnimationTest.prototype.checkImage = function () -{ +AnimationTest.prototype.checkImage = function() { if (this.isTestFinished) { return; } @@ -258,15 +275,13 @@ AnimationTest.prototype.checkImage = function () if (result[0]) { // SUCCESS! - ok(true, "Animated image looks correct, at poll #" - + this.pollCounter); + ok(true, "Animated image looks correct, at poll #" + this.pollCounter); this.cleanUpAndFinish(); } }; -AnimationTest.prototype.takeReferenceSnapshot = function () -{ +AnimationTest.prototype.takeReferenceSnapshot = function() { this.numRefsTaken++; // Test to make sure the reference image doesn't match a clean snapshot @@ -286,15 +301,20 @@ AnimationTest.prototype.takeReferenceSnapshot = function () this.referenceSnapshot = snapshotWindow(window, false); - var snapResult = compareSnapshots(this.cleanSnapshot, - this.referenceSnapshot, false); + var snapResult = compareSnapshots( + this.cleanSnapshot, + this.referenceSnapshot, + false + ); if (!snapResult[0]) { if (this.blankWaitTime > 2000) { // if it took longer than two seconds to load the image, we probably // have a problem. this.wereFailures = true; - ok(snapResult[0], - "Reference snapshot shouldn't match clean (non-image) snapshot"); + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); } else { this.blankWaitTime += currentTest.pollFreq; // let's wait a bit and see if it clears up @@ -303,12 +323,17 @@ AnimationTest.prototype.takeReferenceSnapshot = function () } } - ok(snapResult[0], - "Reference snapshot shouldn't match clean (non-image) snapshot"); + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); var dataString = "Reference Snapshot #" + this.numRefsTaken; - this.outputDebugInfo(dataString, 'refSnapId', - this.referenceSnapshot.toDataURL()); + this.outputDebugInfo( + dataString, + "refSnapId", + this.referenceSnapshot.toDataURL() + ); } else { // Make sure the animation section is hidden this.disableDisplay(document.getElementById(this.imageElementId)); @@ -318,15 +343,20 @@ AnimationTest.prototype.takeReferenceSnapshot = function () this.enableDisplay(referenceDiv); this.referenceSnapshot = snapshotWindow(window, false); - var snapResult = compareSnapshots(this.cleanSnapshot, - this.referenceSnapshot, false); + var snapResult = compareSnapshots( + this.cleanSnapshot, + this.referenceSnapshot, + false + ); if (!snapResult[0]) { if (this.blankWaitTime > 2000) { // if it took longer than two seconds to load the image, we probably // have a problem. this.wereFailures = true; - ok(snapResult[0], - "Reference snapshot shouldn't match clean (non-image) snapshot"); + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); } else { this.blankWaitTime += 20; // let's wait a bit and see if it clears up @@ -335,12 +365,17 @@ AnimationTest.prototype.takeReferenceSnapshot = function () } } - ok(snapResult[0], - "Reference snapshot shouldn't match clean (non-image) snapshot"); + ok( + snapResult[0], + "Reference snapshot shouldn't match clean (non-image) snapshot" + ); var dataString = "Reference Snapshot #" + this.numRefsTaken; - this.outputDebugInfo(dataString, 'refSnapId', - this.referenceSnapshot.toDataURL()); + this.outputDebugInfo( + dataString, + "refSnapId", + this.referenceSnapshot.toDataURL() + ); // Re-hide reference div, and take another snapshot to be sure it's gone this.disableDisplay(referenceDiv); @@ -348,47 +383,46 @@ AnimationTest.prototype.takeReferenceSnapshot = function () } }; -AnimationTest.prototype.enableDisplay = function(element) -{ +AnimationTest.prototype.enableDisplay = function(element) { if (!element) { return; } if (!this.xulTest) { - element.style.display = ''; + element.style.display = ""; } else { - element.setAttribute('hidden', 'false'); + element.setAttribute("hidden", "false"); } }; -AnimationTest.prototype.disableDisplay = function(element) -{ +AnimationTest.prototype.disableDisplay = function(element) { if (!element) { return; } if (!this.xulTest) { - element.style.display = 'none'; + element.style.display = "none"; } else { - element.setAttribute('hidden', 'true'); + element.setAttribute("hidden", "true"); } }; -AnimationTest.prototype.testBlankCameBack = function() -{ +AnimationTest.prototype.testBlankCameBack = function() { var blankSnapshot2 = snapshotWindow(window, false); var result = compareSnapshots(this.blankSnapshot, blankSnapshot2, true); - ok(result[0], "Reference image should disappear when it becomes display:none"); + ok( + result[0], + "Reference image should disappear when it becomes display:none" + ); if (!result[0]) { this.wereFailures = true; var dataString = "Second Blank Snapshot"; - this.outputDebugInfo(dataString, 'blank2SnapId', result[2]); + this.outputDebugInfo(dataString, "blank2SnapId", result[2]); } }; -AnimationTest.prototype.cleanUpAndFinish = function () -{ +AnimationTest.prototype.cleanUpAndFinish = function() { // On the off chance that failTest and checkImage are triggered // back-to-back, use a flag to prevent multiple calls to SimpleTest.finish. if (this.isTestFinished) { @@ -404,7 +438,7 @@ AnimationTest.prototype.cleanUpAndFinish = function () } if (this.wereFailures) { - document.getElementById(this.debugElementId).style.display = 'block'; + document.getElementById(this.debugElementId).style.display = "block"; } SimpleTest.finish(); diff --git a/image/test/mochitest/imgutils.js b/image/test/mochitest/imgutils.js index f658cfd55e95..cd24c7ede875 100644 --- a/image/test/mochitest/imgutils.js +++ b/image/test/mochitest/imgutils.js @@ -1,54 +1,51 @@ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ // Helper file for shared image functionality -// +// // Note that this is use by tests elsewhere in the source tree. When in doubt, // check mxr before removing or changing functionality. // Helper function to clear both the content and chrome image caches -function clearAllImageCaches() -{ - var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"] - .getService(SpecialPowers.Ci.imgITools); +function clearAllImageCaches() { + var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService( + SpecialPowers.Ci.imgITools + ); var imageCache = tools.getImgCacheForDocument(window.document); - imageCache.clearCache(true); // true=chrome + imageCache.clearCache(true); // true=chrome imageCache.clearCache(false); // false=content } // Helper function to clear the image cache of content images -function clearImageCache() -{ - var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"] - .getService(SpecialPowers.Ci.imgITools); +function clearImageCache() { + var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"].getService( + SpecialPowers.Ci.imgITools + ); var imageCache = tools.getImgCacheForDocument(window.document); imageCache.clearCache(false); // true=chrome, false=content } // Helper function to determine if the frame is decoded for a given image id -function isFrameDecoded(id) -{ - return (getImageStatus(id) & - SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE) - ? true : false; +function isFrameDecoded(id) { + return getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE + ? true + : false; } // Helper function to determine if the image is loaded for a given image id -function isImageLoaded(id) -{ - return (getImageStatus(id) & - SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE) - ? true : false; +function isImageLoaded(id) { + return getImageStatus(id) & SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE + ? true + : false; } // Helper function to get the status flags of an image -function getImageStatus(id) -{ +function getImageStatus(id) { // Get the image var img = SpecialPowers.wrap(document.getElementById(id)); // Get the request - var request = img.getRequest(SpecialPowers.Ci - .nsIImageLoadingContent - .CURRENT_REQUEST); + var request = img.getRequest( + SpecialPowers.Ci.nsIImageLoadingContent.CURRENT_REQUEST + ); // Return the status return request.imageStatus; @@ -56,8 +53,7 @@ function getImageStatus(id) // Forces a synchronous decode of an image by drawing it to a canvas. Only // really meaningful if the image is fully loaded first -function forceDecode(id) -{ +function forceDecode(id) { // Get the image var img = document.getElementById(id); @@ -69,25 +65,36 @@ function forceDecode(id) ctx.drawImage(img, 0, 0); } - // Functions to facilitate getting/setting various image-related prefs // -// If you change a pref in a mochitest, Don't forget to reset it to its +// If you change a pref in a mochitest, Don't forget to reset it to its // original value! // // Null indicates no pref set -const DISCARD_ENABLED_PREF = {name: "discardable", branch: "image.mem.", type: "bool"}; -const DECODEONDRAW_ENABLED_PREF = {name: "decodeondraw", branch: "image.mem.", type: "bool"}; -const DISCARD_TIMEOUT_PREF = {name: "min_discard_timeout_ms", branch: "image.mem.", type: "int"}; +const DISCARD_ENABLED_PREF = { + name: "discardable", + branch: "image.mem.", + type: "bool", +}; +const DECODEONDRAW_ENABLED_PREF = { + name: "decodeondraw", + branch: "image.mem.", + type: "bool", +}; +const DISCARD_TIMEOUT_PREF = { + name: "min_discard_timeout_ms", + branch: "image.mem.", + type: "int", +}; -function setImagePref(pref, val) -{ - var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"] - .getService(SpecialPowers.Ci.nsIPrefService); +function setImagePref(pref, val) { + var prefService = SpecialPowers.Cc[ + "@mozilla.org/preferences-service;1" + ].getService(SpecialPowers.Ci.nsIPrefService); var branch = prefService.getBranch(pref.branch); if (val != null) { - switch(pref.type) { + switch (pref.type) { case "bool": branch.setBoolPref(pref.name, val); break; @@ -97,15 +104,15 @@ function setImagePref(pref, val) default: throw new Error("Unknown pref type"); } - } - else if (branch.prefHasUserValue(pref.name)) + } else if (branch.prefHasUserValue(pref.name)) { branch.clearUserPref(pref.name); + } } -function getImagePref(pref) -{ - var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"] - .getService(SpecialPowers.Ci.nsIPrefService); +function getImagePref(pref) { + var prefService = SpecialPowers.Cc[ + "@mozilla.org/preferences-service;1" + ].getService(SpecialPowers.Ci.nsIPrefService); var branch = prefService.getBranch(pref.branch); if (branch.prefHasUserValue(pref.name)) { switch (pref.type) { @@ -116,20 +123,19 @@ function getImagePref(pref) default: throw new Error("Unknown pref type"); } - } - else + } else { return null; + } } // JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods. -function ImageDecoderObserverStub() -{ - this.sizeAvailable = function sizeAvailable(aRequest) {} - this.frameComplete = function frameComplete(aRequest) {} - this.decodeComplete = function decodeComplete(aRequest) {} - this.loadComplete = function loadComplete(aRequest) {} - this.frameUpdate = function frameUpdate(aRequest) {} - this.discard = function discard(aRequest) {} - this.isAnimated = function isAnimated(aRequest) {} - this.hasTransparency = function hasTransparency(aRequest) {} +function ImageDecoderObserverStub() { + this.sizeAvailable = function sizeAvailable(aRequest) {}; + this.frameComplete = function frameComplete(aRequest) {}; + this.decodeComplete = function decodeComplete(aRequest) {}; + this.loadComplete = function loadComplete(aRequest) {}; + this.frameUpdate = function frameUpdate(aRequest) {}; + this.discard = function discard(aRequest) {}; + this.isAnimated = function isAnimated(aRequest) {}; + this.hasTransparency = function hasTransparency(aRequest) {}; } diff --git a/image/test/unit/async_load_tests.js b/image/test/unit/async_load_tests.js index 843b15e85520..84e6058b87e3 100644 --- a/image/test/unit/async_load_tests.js +++ b/image/test/unit/async_load_tests.js @@ -6,23 +6,21 @@ * var uri. */ -const {HttpServer} = ChromeUtils.import("resource://testing-common/httpd.js"); -const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js"); +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); var server = new HttpServer(); -server.registerDirectory("/", do_get_file('')); +server.registerDirectory("/", do_get_file("")); server.registerContentType("sjs", "sjs"); server.start(-1); - -load('image_load_helpers.js'); +load("image_load_helpers.js"); var requests = []; // Return a closure that holds on to the listener from the original // imgIRequest, and compares its results to the cloned one. -function getCloneStopCallback(original_listener) -{ +function getCloneStopCallback(original_listener) { return function cloneStop(listener) { Assert.equal(original_listener.state, listener.state); @@ -30,35 +28,38 @@ function getCloneStopCallback(original_listener) // twice. Assert.notEqual(original_listener, listener); do_test_finished(); - } + }; } // Make sure that cloned requests get all the same callbacks as the original, // but they aren't synchronous right now. -function checkClone(other_listener, aRequest) -{ +function checkClone(other_listener, aRequest) { do_test_pending(); // For as long as clone notification is synchronous, we can't test the clone state reliably. - var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /* getCloneStopCallback(other_listener)*/); + var listener = new ImageListener( + null, + function(foo, bar) { + do_test_finished(); + } /* getCloneStopCallback(other_listener)*/ + ); listener.synchronous = false; - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener); var clone = aRequest.clone(outer); requests.push({ request: clone, locked: false }); } // Ensure that all the callbacks were called on aRequest. -function checkSizeAndLoad(listener, aRequest) -{ +function checkSizeAndLoad(listener, aRequest) { Assert.notEqual(listener.state & SIZE_AVAILABLE, 0); Assert.notEqual(listener.state & LOAD_COMPLETE, 0); do_test_finished(); } -function secondLoadDone(oldlistener, aRequest) -{ +function secondLoadDone(oldlistener, aRequest) { do_test_pending(); try { @@ -68,11 +69,12 @@ function secondLoadDone(oldlistener, aRequest) // clone state reliably. var listener = new ImageListener(null, checkSizeAndLoad); listener.synchronous = false; - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener); var staticrequestclone = staticrequest.clone(outer); requests.push({ request: staticrequestclone, locked: false }); - } catch(e) { + } catch (e) { // We can't create a static request. Most likely the request we started // with didn't load successfully. do_test_finished(); @@ -85,22 +87,32 @@ function secondLoadDone(oldlistener, aRequest) // Load the request a second time. This should come from the image cache, and // therefore would be at most risk of being served synchronously. -function checkSecondLoad() -{ +function checkSecondLoad() { do_test_pending(); var listener = new ImageListener(checkClone, secondLoadDone); - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener); requests.push({ - request: gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null), + request: gCurrentLoader.loadImageXPCOM( + uri, + null, + null, + "default", + null, + null, + outer, + null, + 0, + null + ), locked: false, }); listener.synchronous = false; } -function firstLoadDone(oldlistener, aRequest) -{ +function firstLoadDone(oldlistener, aRequest) { checkSecondLoad(uri); do_test_finished(); @@ -108,33 +120,37 @@ function firstLoadDone(oldlistener, aRequest) // Return a closure that allows us to check the stream listener's status when the // image finishes loading. -function getChannelLoadImageStopCallback(streamlistener, next) -{ +function getChannelLoadImageStopCallback(streamlistener, next) { return function channelLoadStop(imglistener, aRequest) { - next(); do_test_finished(); - } + }; } // Load the request a second time. This should come from the image cache, and // therefore would be at most risk of being served synchronously. -function checkSecondChannelLoad() -{ +function checkSecondChannelLoad() { do_test_pending(); - var channel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); + var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); var channellistener = new ChannelListener(); channel.asyncOpen(channellistener); - var listener = new ImageListener(null, - getChannelLoadImageStopCallback(channellistener, - all_done_callback)); - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener); + var listener = new ImageListener( + null, + getChannelLoadImageStopCallback(channellistener, all_done_callback) + ); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener); var outlistener = {}; requests.push({ - request: gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener), + request: gCurrentLoader.loadImageWithChannelXPCOM( + channel, + outer, + null, + outlistener + ), locked: false, }); channellistener.outputListener = outlistener.value; @@ -142,24 +158,32 @@ function checkSecondChannelLoad() listener.synchronous = false; } -function run_loadImageWithChannel_tests() -{ +function run_loadImageWithChannel_tests() { // To ensure we're testing what we expect to, create a new loader and cache. - gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader); + gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance( + Ci.imgILoader + ); do_test_pending(); - var channel = NetUtil.newChannel({uri, loadUsingSystemPrincipal: true}); + var channel = NetUtil.newChannel({ uri, loadUsingSystemPrincipal: true }); var channellistener = new ChannelListener(); channel.asyncOpen(channellistener); - var listener = new ImageListener(null, - getChannelLoadImageStopCallback(channellistener, - checkSecondChannelLoad)); - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener); + var listener = new ImageListener( + null, + getChannelLoadImageStopCallback(channellistener, checkSecondChannelLoad) + ); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener); var outlistener = {}; requests.push({ - request: gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener), + request: gCurrentLoader.loadImageWithChannelXPCOM( + channel, + outer, + null, + outlistener + ), locked: false, }); channellistener.outputListener = outlistener.value; @@ -167,54 +191,84 @@ function run_loadImageWithChannel_tests() listener.synchronous = false; } -function all_done_callback() -{ - server.stop(function() { do_test_finished(); }); +function all_done_callback() { + server.stop(function() { + do_test_finished(); + }); } -function startImageCallback(otherCb) -{ - return function(listener, request) - { +function startImageCallback(otherCb) { + return function(listener, request) { // Make sure we can load the same image immediately out of the cache. do_test_pending(); - var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); }); - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener2); + var listener2 = new ImageListener(null, function(foo, bar) { + do_test_finished(); + }); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener2); requests.push({ - request: gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null), + request: gCurrentLoader.loadImageXPCOM( + uri, + null, + null, + "default", + null, + null, + outer, + null, + 0, + null + ), locked: false, }); listener2.synchronous = false; // Now that we've started another load, chain to the callback. otherCb(listener, request); - } + }; } var gCurrentLoader; -function cleanup() -{ - for (let {request, locked} of requests) { +function cleanup() { + for (let { request, locked } of requests) { if (locked) { - try { request.unlockImage() } catch (e) {} + try { + request.unlockImage(); + } catch (e) {} } request.cancelAndForgetObserver(0); } } -function run_test() -{ +function run_test() { registerCleanupFunction(cleanup); - gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader); + gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance( + Ci.imgILoader + ); do_test_pending(); - var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone); - var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools) - .createScriptedObserver(listener); - var req = gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null); + var listener = new ImageListener( + startImageCallback(checkClone), + firstLoadDone + ); + var outer = Cc["@mozilla.org/image/tools;1"] + .getService(Ci.imgITools) + .createScriptedObserver(listener); + var req = gCurrentLoader.loadImageXPCOM( + uri, + null, + null, + "default", + null, + null, + outer, + null, + 0, + null + ); // Ensure that we don't cause any mayhem when we lock an image. req.lockImage(); diff --git a/image/test/unit/image_load_helpers.js b/image/test/unit/image_load_helpers.js index b1ba13dae1a1..6d1e605bf528 100644 --- a/image/test/unit/image_load_helpers.js +++ b/image/test/unit/image_load_helpers.js @@ -21,44 +21,37 @@ do_get_profile(); // An implementation of imgIScriptedNotificationObserver with the ability to // call specified functions on onStartRequest and onStopRequest. -function ImageListener(start_callback, stop_callback) -{ - this.sizeAvailable = function onSizeAvailable(aRequest) - { +function ImageListener(start_callback, stop_callback) { + this.sizeAvailable = function onSizeAvailable(aRequest) { Assert.ok(!this.synchronous); this.state |= SIZE_AVAILABLE; - if (this.start_callback) + if (this.start_callback) { this.start_callback(this, aRequest); - } - this.frameComplete = function onFrameComplete(aRequest) - { + } + }; + this.frameComplete = function onFrameComplete(aRequest) { Assert.ok(!this.synchronous); this.state |= FRAME_COMPLETE; - } - this.decodeComplete = function onDecodeComplete(aRequest) - { + }; + this.decodeComplete = function onDecodeComplete(aRequest) { Assert.ok(!this.synchronous); this.state |= DECODE_COMPLETE; - } - this.loadComplete = function onLoadcomplete(aRequest) - { + }; + this.loadComplete = function onLoadcomplete(aRequest) { Assert.ok(!this.synchronous); this.state |= LOAD_COMPLETE; - if (this.stop_callback) + if (this.stop_callback) { this.stop_callback(this, aRequest); - } - this.frameUpdate = function onFrameUpdate(aRequest) - { - } - this.isAnimated = function onIsAnimated() - { - } + } + }; + this.frameUpdate = function onFrameUpdate(aRequest) {}; + this.isAnimated = function onIsAnimated() {}; // Initialize the synchronous flag to true to start. This must be set to // false before exiting to the event loop! @@ -76,41 +69,50 @@ function ImageListener(start_callback, stop_callback) this.state = 0; } -function NS_FAILED(val) -{ +function NS_FAILED(val) { return !!(val & 0x80000000); } -function ChannelListener() -{ - this.onStartRequest = function onStartRequest(aRequest) - { - if (this.outputListener) +function ChannelListener() { + this.onStartRequest = function onStartRequest(aRequest) { + if (this.outputListener) { this.outputListener.onStartRequest(aRequest); + } this.requestStatus |= START_REQUEST; - } + }; - this.onDataAvailable = function onDataAvailable(aRequest, aInputStream, aOffset, aCount) - { - if (this.outputListener) - this.outputListener.onDataAvailable(aRequest, aInputStream, aOffset, aCount); + this.onDataAvailable = function onDataAvailable( + aRequest, + aInputStream, + aOffset, + aCount + ) { + if (this.outputListener) { + this.outputListener.onDataAvailable( + aRequest, + aInputStream, + aOffset, + aCount + ); + } this.requestStatus |= DATA_AVAILABLE; - } + }; - this.onStopRequest = function onStopRequest(aRequest, aStatusCode) - { - if (this.outputListener) + this.onStopRequest = function onStopRequest(aRequest, aStatusCode) { + if (this.outputListener) { this.outputListener.onStopRequest(aRequest, aStatusCode); + } // If we failed (or were canceled - failure is implied if canceled), // there's no use tracking our state, since it's meaningless. - if (NS_FAILED(aStatusCode)) + if (NS_FAILED(aStatusCode)) { this.requestStatus = 0; - else + } else { this.requestStatus |= STOP_REQUEST; - } + } + }; // A listener to pass the notifications we get to. this.outputListener = null; diff --git a/image/test/unit/test_async_notification.js b/image/test/unit/test_async_notification.js index eef3a9a4960c..f9246b61df33 100644 --- a/image/test/unit/test_async_notification.js +++ b/image/test/unit/test_async_notification.js @@ -3,8 +3,11 @@ */ // A simple 3x3 png; rows go red, green, blue. Stolen from the PNG encoder test. -var pngspec = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="; -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); +var pngspec = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII="; +var ioService = Cc["@mozilla.org/network/io-service;1"].getService( + Ci.nsIIOService +); var uri = ioService.newURI(pngspec); -load('async_load_tests.js'); +load("async_load_tests.js"); diff --git a/image/test/unit/test_async_notification_404.js b/image/test/unit/test_async_notification_404.js index ec0e966a4378..aae98b2a50ba 100644 --- a/image/test/unit/test_async_notification_404.js +++ b/image/test/unit/test_async_notification_404.js @@ -2,15 +2,20 @@ * Test to ensure that load/decode notifications are delivered completely and * asynchronously when dealing with a file that's a 404. */ -const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); -var ioService = Cc["@mozilla.org/network/io-service;1"] - .getService(Ci.nsIIOService); +var ioService = Cc["@mozilla.org/network/io-service;1"].getService( + Ci.nsIIOService +); XPCOMUtils.defineLazyGetter(this, "uri", function() { - return ioService.newURI("http://localhost:" + - server.identity.primaryPort + - "/async-notification-never-here.jpg"); + return ioService.newURI( + "http://localhost:" + + server.identity.primaryPort + + "/async-notification-never-here.jpg" + ); }); -load('async_load_tests.js'); +load("async_load_tests.js"); diff --git a/image/test/unit/test_async_notification_animated.js b/image/test/unit/test_async_notification_animated.js index e330eb113e0c..09bea251096a 100644 --- a/image/test/unit/test_async_notification_animated.js +++ b/image/test/unit/test_async_notification_animated.js @@ -7,8 +7,11 @@ */ // transparent-animation.gif from the gif reftests. -var spec = "data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs="; -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); +var spec = + "data:image/gif;base64,R0lGODlhZABkAIABAP8AAP///yH5BAkBAAEALAAAAABLAGQAAAK8jI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8YhMKpchgPMJjUqnVOipis1ir9qul+sNV8HistVkTj/JajG7/UXDy+95tm4fy/NdPF/q93dWIqgVWAhwWKgoyPjnyAeZJ2lHOWcJh9mmqcaZ5mkGSreHOCXqRloadRrGGkeoapoa6+TaN0tra4gbq3vHq+q7BVwqrMeEnKy8zNzs/AwdLT1NXW19jZ1tUgAAIfkECQEAAQAsAAAAADQAZAAAArCMj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/7vAAiHxKLxiCRCkswmc+mMSqHSapJqzSof2u4Q67WCw1MuOTs+N9Pqq7kdZcON8vk2aF+/88g6358HaCc4Rwhn2IaopnjGSOYYBukl2UWpZYm2x0enuXnX4NnXGQqAKTYaalqlWoZH+snwWsQah+pJ64Sr5ypbCvQLHCw8TFxsfIycrLzM3PxQAAAh+QQJAQABACwAAAAAGwBkAAACUIyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gTE8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvdrfYnH5LL5jE6r16sCADs="; +var ioService = Cc["@mozilla.org/network/io-service;1"].getService( + Ci.nsIIOService +); var uri = ioService.newURI(spec); -load('async_load_tests.js'); +load("async_load_tests.js"); diff --git a/image/test/unit/test_encoder_apng.js b/image/test/unit/test_encoder_apng.js index 3b000a33bca3..1c9d3a5d96f5 100644 --- a/image/test/unit/test_encoder_apng.js +++ b/image/test/unit/test_encoder_apng.js @@ -3,465 +3,1094 @@ * */ - - // dispose=[none|background|previous] - // blend=[source|over] +// dispose=[none|background|previous] +// blend=[source|over] var apng1A = { - // A 3x3 image with 3 frames, alternating red, green, blue. RGB format. - width : 3, height : 3, skipFirstFrame : false, - format : Ci.imgIEncoder.INPUT_FORMAT_RGB, - transparency : null, - plays : 0, + // A 3x3 image with 3 frames, alternating red, green, blue. RGB format. + width: 3, + height: 3, + skipFirstFrame: false, + format: Ci.imgIEncoder.INPUT_FORMAT_RGB, + transparency: null, + plays: 0, - frames : [ - { // frame #1 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + frames: [ + { + // frame #1 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9, - transparency : null, + format: Ci.imgIEncoder.INPUT_FORMAT_RGB, + stride: 9, + transparency: null, - pixels : [ - 255,0,0, 255,0,0, 255,0,0, - 255,0,0, 255,0,0, 255,0,0, - 255,0,0, 255,0,0, 255,0,0 - ] - }, + pixels: [ + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + ], + }, - { // frame #2 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + { + // frame #2 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9, - transparency : null, + format: Ci.imgIEncoder.INPUT_FORMAT_RGB, + stride: 9, + transparency: null, - pixels : [ - 0,255,0, 0,255,0, 0,255,0, - 0,255,0, 0,255,0, 0,255,0, - 0,255,0, 0,255,0, 0,255,0 - ] - }, + pixels: [ + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + ], + }, - { // frame #3 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + { + // frame #3 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9, - transparency : null, + format: Ci.imgIEncoder.INPUT_FORMAT_RGB, + stride: 9, + transparency: null, - pixels : [ - 0,0,255, 0,0,255, 0,0,255, - 0,0,255, 0,0,255, 0,0,255, - 0,0,255, 0,0,255, 0,0,255 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABBJREFUCJlj+M/AAEEMWFgAj44I+H2CySsAAAAaZmNUTAAAAAEAAAADAAAAAwAAAAAAAAAAAfQD6AAA7mXKzAAAABNmZEFUAAAAAgiZY2D4zwBFWFgAhpcI+I731VcAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABNmZEFUAAAABAiZY2Bg+A9DmCwAfaAI+AGmQVoAAAAASUVORK5CYII=" + pixels: [ + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABBJREFUCJlj+M/AAEEMWFgAj44I+H2CySsAAAAaZmNUTAAAAAEAAAADAAAAAwAAAAAAAAAAAfQD6AAA7mXKzAAAABNmZEFUAAAAAgiZY2D4zwBFWFgAhpcI+I731VcAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABNmZEFUAAAABAiZY2Bg+A9DmCwAfaAI+AGmQVoAAAAASUVORK5CYII=", }; - var apng1B = { - // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. - width : 3, height : 3, skipFirstFrame : false, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, - transparency : null, - plays : 0, + // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. + width: 3, + height: 3, + skipFirstFrame: false, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + transparency: null, + plays: 0, - frames : [ - { // frame #1 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + frames: [ + { + // frame #1 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255 - ] - }, + pixels: [ + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + ], + }, - { // frame #2 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + { + // frame #2 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,255,0,255, 0,255,0,255, 0,255,0,255, - 0,255,0,255, 0,255,0,255, 0,255,0,255, - 0,255,0,255, 0,255,0,255, 0,255,0,255 - ] - }, + pixels: [ + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + ], + }, - { // frame #3 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + { + // frame #3 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,0,255,255, 0,0,255,255, 0,0,255,255, - 0,0,255,255, 0,0,255,255, 0,0,255,255, - 0,0,255,255, 0,0,255,255, 0,0,255,255 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAO5lyswAAAASZmRBVAAAAAIImWNg+I8EcXIAVOAR77Vyl9QAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABRmZEFUAAAABAiZY2Bg+P8fgXFxAEvpEe8rClxSAAAAAElFTkSuQmCC" + pixels: [ + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAO5lyswAAAASZmRBVAAAAAIImWNg+I8EcXIAVOAR77Vyl9QAAAAaZmNUTAAAAAMAAAADAAAAAwAAAAAAAAAAAfQD6AAAA/MZJQAAABRmZEFUAAAABAiZY2Bg+P8fgXFxAEvpEe8rClxSAAAAAElFTkSuQmCC", }; - var apng1C = { - // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. - // The first frame is skipped, so it will only flash green/blue (or static red in an APNG-unaware viewer) - width : 3, height : 3, skipFirstFrame : true, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, - transparency : null, - plays : 0, + // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. + // The first frame is skipped, so it will only flash green/blue (or static red in an APNG-unaware viewer) + width: 3, + height: 3, + skipFirstFrame: true, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + transparency: null, + plays: 0, - frames : [ - { // frame #1 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + frames: [ + { + // frame #1 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255 - ] - }, + pixels: [ + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + ], + }, - { // frame #2 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + { + // frame #2 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,255,0,255, 0,255,0,255, 0,255,0,255, - 0,255,0,255, 0,255,0,255, 0,255,0,255, - 0,255,0,255, 0,255,0,255, 0,255,0,255 - ] - }, + pixels: [ + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 255, + ], + }, - { // frame #3 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + { + // frame #3 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,0,255,255, 0,0,255,255, 0,0,255,255, - 0,0,255,255, 0,0,255,255, 0,0,255,255, - 0,0,255,255, 0,0,255,255, 0,0,255,255 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAACAAAAAPONk3AAAAARSURBVAiZY/jPwPAfhhlwcgBd1xHvwqIidQAAABpmY1RMAAAAAAAAAAMAAAADAAAAAAAAAAAB9APoAAB1FiAYAAAAEmZkQVQAAAABCJljYPiPBHFyAFTgEe+kD/2tAAAAGmZjVEwAAAACAAAAAwAAAAMAAAAAAAAAAAH0A+gAAJiA8/EAAAAUZmRBVAAAAAMImWNgYPj/H4FxcQBL6RHvC5ggGQAAAABJRU5ErkJggg==" + pixels: [ + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAACAAAAAPONk3AAAAARSURBVAiZY/jPwPAfhhlwcgBd1xHvwqIidQAAABpmY1RMAAAAAAAAAAMAAAADAAAAAAAAAAAB9APoAAB1FiAYAAAAEmZkQVQAAAABCJljYPiPBHFyAFTgEe+kD/2tAAAAGmZjVEwAAAACAAAAAwAAAAMAAAAAAAAAAAH0A+gAAJiA8/EAAAAUZmRBVAAAAAMImWNgYPj/H4FxcQBL6RHvC5ggGQAAAABJRU5ErkJggg==", }; - var apng2A = { - // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. - // blend = over mode - // (The green frame is a horizontal gradient, and the blue frame is a - // vertical gradient. They stack as they animate.) - width : 3, height : 3, skipFirstFrame : false, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, - transparency : null, - plays : 0, + // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. + // blend = over mode + // (The green frame is a horizontal gradient, and the blue frame is a + // vertical gradient. They stack as they animate.) + width: 3, + height: 3, + skipFirstFrame: false, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + transparency: null, + plays: 0, - frames : [ - { // frame #1 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + frames: [ + { + // frame #1 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255 - ] - }, + pixels: [ + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + ], + }, - { // frame #2 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "over", delay : 500, + { + // frame #2 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "over", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,255,0,255, 0,255,0,180, 0,255,0,75, - 0,255,0,255, 0,255,0,180, 0,255,0,75, - 0,255,0,255, 0,255,0,180, 0,255,0,75 - ] - }, + pixels: [ + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 180, + 0, + 255, + 0, + 75, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 180, + 0, + 255, + 0, + 75, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 180, + 0, + 255, + 0, + 75, + ], + }, - { // frame #3 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "over", delay : 500, + { + // frame #3 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "over", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,0,255,75, 0,0,255,75, 0,0,255,75, - 0,0,255,180, 0,0,255,180, 0,0,255,180, - 0,0,255,255, 0,0,255,255, 0,0,255,255 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAZli+loAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gAAXT0KbMAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC" + pixels: [ + 0, + 0, + 255, + 75, + 0, + 0, + 255, + 75, + 0, + 0, + 255, + 75, + 0, + 0, + 255, + 180, + 0, + 0, + 255, + 180, + 0, + 0, + 255, + 180, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gAAZli+loAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gAAXT0KbMAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC", }; - var apng2B = { - // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. - // blend = over, dispose = background - // (The green frame is a horizontal gradient, and the blue frame is a - // vertical gradient. Each frame is displayed individually, blended to - // whatever the background is.) - width : 3, height : 3, skipFirstFrame : false, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, - transparency : null, - plays : 0, + // A 3x3 image with 3 frames, alternating red, green, blue. RGBA format. + // blend = over, dispose = background + // (The green frame is a horizontal gradient, and the blue frame is a + // vertical gradient. Each frame is displayed individually, blended to + // whatever the background is.) + width: 3, + height: 3, + skipFirstFrame: false, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + transparency: null, + plays: 0, - frames : [ - { // frame #1 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "background", blend : "source", delay : 500, + frames: [ + { + // frame #1 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "background", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255, - 255,0,0,255, 255,0,0,255, 255,0,0,255 - ] - }, + pixels: [ + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + ], + }, - { // frame #2 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "background", blend : "over", delay : 500, + { + // frame #2 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "background", + blend: "over", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,255,0,255, 0,255,0,180, 0,255,0,75, - 0,255,0,255, 0,255,0,180, 0,255,0,75, - 0,255,0,255, 0,255,0,180, 0,255,0,75 - ] - }, + pixels: [ + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 180, + 0, + 255, + 0, + 75, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 180, + 0, + 255, + 0, + 75, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 180, + 0, + 255, + 0, + 75, + ], + }, - { // frame #3 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "background", blend : "over", delay : 500, + { + // frame #3 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "background", + blend: "over", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 0,0,255,75, 0,0,255,75, 0,0,255,75, - 0,0,255,180, 0,0,255,180, 0,0,255,180, - 0,0,255,255, 0,0,255,255, 0,0,255,255 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AEAbA0RWQAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gBAYB5yxsAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gBAW3vGPIAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC" + pixels: [ + 0, + 0, + 255, + 75, + 0, + 0, + 255, + 75, + 0, + 0, + 255, + 75, + 0, + 0, + 255, + 180, + 0, + 0, + 255, + 180, + 0, + 0, + 255, + 180, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAADAAAAAM7tusAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AEAbA0RWQAAABFJREFUCJlj+M/A8B+GGXByAF3XEe/CoiJ1AAAAGmZjVEwAAAABAAAAAwAAAAMAAAAAAAAAAAH0A+gBAYB5yxsAAAAcZmRBVAAAAAIImWNg+M/wn+E/wxaG/wzeDDg5ACeGDvKVa3pyAAAAGmZjVEwAAAADAAAAAwAAAAMAAAAAAAAAAAH0A+gBAW3vGPIAAAAcZmRBVAAAAAQImWNgYPjvjcAM/7cgMMP//zAMAPqkDvLn1m3SAAAAAElFTkSuQmCC", }; - var apng3 = { - // A 3x3 image with 4 frames. First frame is white, then 1x1 frames draw a diagonal line - width : 3, height : 3, skipFirstFrame : false, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, - transparency : null, - plays : 0, + // A 3x3 image with 4 frames. First frame is white, then 1x1 frames draw a diagonal line + width: 3, + height: 3, + skipFirstFrame: false, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + transparency: null, + plays: 0, - frames : [ - { // frame #1 - width : 3, height : 3, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + frames: [ + { + // frame #1 + width: 3, + height: 3, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ + pixels: [ + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + ], + }, - 255,255,255,255, 255,255,255,255, 255,255,255,255, - 255,255,255,255, 255,255,255,255, 255,255,255,255, - 255,255,255,255, 255,255,255,255, 255,255,255,255 - ] - }, + { + // frame #2 + width: 1, + height: 1, + x_offset: 0, + y_offset: 0, + dispose: "none", + blend: "source", + delay: 500, - { // frame #2 - width : 1, height : 1, - x_offset : 0, y_offset : 0, - dispose : "none", blend : "source", delay : 500, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + pixels: [0, 0, 0, 255], + }, - pixels : [ - 0,0,0,255 - ] - }, + { + // frame #3 + width: 1, + height: 1, + x_offset: 1, + y_offset: 1, + dispose: "none", + blend: "source", + delay: 500, - { // frame #3 - width : 1, height : 1, - x_offset : 1, y_offset : 1, - dispose : "none", blend : "source", delay : 500, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + pixels: [0, 0, 0, 255], + }, - pixels : [ - 0,0,0,255 - ] - }, + { + // frame #4 + width: 1, + height: 1, + x_offset: 2, + y_offset: 2, + dispose: "none", + blend: "source", + delay: 500, - { // frame #4 - width : 1, height : 1, - x_offset : 2, y_offset : 2, - dispose : "none", blend : "source", delay : 500, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + pixels: [0, 0, 0, 255], + }, + ], - pixels : [ - 0,0,0,255 - ] - } - ], - - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAAEAAAAAHzNZtAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAAA5JREFUCJlj+I8EGHByALuHI91kueRqAAAAGmZjVEwAAAABAAAAAQAAAAEAAAAAAAAAAAH0A+gAADJXfawAAAARZmRBVAAAAAIImWNgYGD4DwABBAEAbr5mpgAAABpmY1RMAAAAAwAAAAEAAAABAAAAAQAAAAEB9APoAAC4OHoxAAAAEWZkQVQAAAAECJljYGBg+A8AAQQBAJZ8LRAAAAAaZmNUTAAAAAUAAAABAAAAAQAAAAIAAAACAfQD6AAA/fh01wAAABFmZEFUAAAABgiZY2BgYPgPAAEEAQB3Eum9AAAAAElFTkSuQmCC" + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAACGFjVEwAAAAEAAAAAHzNZtAAAAAaZmNUTAAAAAAAAAADAAAAAwAAAAAAAAAAAfQD6AAAdRYgGAAAAA5JREFUCJlj+I8EGHByALuHI91kueRqAAAAGmZjVEwAAAABAAAAAQAAAAEAAAAAAAAAAAH0A+gAADJXfawAAAARZmRBVAAAAAIImWNgYGD4DwABBAEAbr5mpgAAABpmY1RMAAAAAwAAAAEAAAABAAAAAQAAAAEB9APoAAC4OHoxAAAAEWZkQVQAAAAECJljYGBg+A8AAQQBAJZ8LRAAAAAaZmNUTAAAAAUAAAABAAAAAQAAAAIAAAACAfQD6AAA/fh01wAAABFmZEFUAAAABgiZY2BgYPgPAAEEAQB3Eum9AAAAAElFTkSuQmCC", }; // Main test entry point. function run_test() { - dump("Checking apng1A...\n"); - run_test_for(apng1A); - dump("Checking apng1B...\n"); - run_test_for(apng1B); - dump("Checking apng1C...\n"); - run_test_for(apng1C); + dump("Checking apng1A...\n"); + run_test_for(apng1A); + dump("Checking apng1B...\n"); + run_test_for(apng1B); + dump("Checking apng1C...\n"); + run_test_for(apng1C); - dump("Checking apng2A...\n"); - run_test_for(apng2A); - dump("Checking apng2B...\n"); - run_test_for(apng2B); + dump("Checking apng2A...\n"); + run_test_for(apng2A); + dump("Checking apng2B...\n"); + run_test_for(apng2B); - dump("Checking apng3...\n"); - run_test_for(apng3); -}; - - -function run_test_for(input) { - var encoder, dataURL; - - encoder = encodeImage(input); - dataURL = makeDataURL(encoder, "image/png"); - Assert.equal(dataURL, input.expected); -}; - - -function encodeImage(input) { - var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance(); - encoder.QueryInterface(Ci.imgIEncoder); - - var options = ""; - if (input.transparency) { options += "transparency=" + input.transparency; } - options += ";frames=" + input.frames.length; - options += ";skipfirstframe=" + (input.skipFirstFrame ? "yes" : "no"); - options += ";plays=" + input.plays; - encoder.startImageEncode(input.width, input.height, input.format, options); - - for (var i = 0; i < input.frames.length; i++) { - var frame = input.frames[i]; - - options = ""; - if (frame.transparency) { options += "transparency=" + input.transparency; } - options += ";delay=" + frame.delay; - options += ";dispose=" + frame.dispose; - options += ";blend=" + frame.blend; - if (frame.x_offset > 0) { options += ";xoffset=" + frame.x_offset; } - if (frame.y_offset > 0) { options += ";yoffset=" + frame.y_offset; } - - encoder.addImageFrame(frame.pixels, frame.pixels.length, - frame.width, frame.height, frame.stride, frame.format, options); - } - - encoder.endImageEncode(); - - return encoder; + dump("Checking apng3...\n"); + run_test_for(apng3); } +function run_test_for(input) { + var encoder, dataURL; + + encoder = encodeImage(input); + dataURL = makeDataURL(encoder, "image/png"); + Assert.equal(dataURL, input.expected); +} + +function encodeImage(input) { + var encoder = Cc[ + "@mozilla.org/image/encoder;2?type=image/png" + ].createInstance(); + encoder.QueryInterface(Ci.imgIEncoder); + + var options = ""; + if (input.transparency) { + options += "transparency=" + input.transparency; + } + options += ";frames=" + input.frames.length; + options += ";skipfirstframe=" + (input.skipFirstFrame ? "yes" : "no"); + options += ";plays=" + input.plays; + encoder.startImageEncode(input.width, input.height, input.format, options); + + for (var i = 0; i < input.frames.length; i++) { + var frame = input.frames[i]; + + options = ""; + if (frame.transparency) { + options += "transparency=" + input.transparency; + } + options += ";delay=" + frame.delay; + options += ";dispose=" + frame.dispose; + options += ";blend=" + frame.blend; + if (frame.x_offset > 0) { + options += ";xoffset=" + frame.x_offset; + } + if (frame.y_offset > 0) { + options += ";yoffset=" + frame.y_offset; + } + + encoder.addImageFrame( + frame.pixels, + frame.pixels.length, + frame.width, + frame.height, + frame.stride, + frame.format, + options + ); + } + + encoder.endImageEncode(); + + return encoder; +} function makeDataURL(encoder, mimetype) { - var rawStream = encoder.QueryInterface(Ci.nsIInputStream); + var rawStream = encoder.QueryInterface(Ci.nsIInputStream); - var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(); - stream.QueryInterface(Ci.nsIBinaryInputStream); + var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(); + stream.QueryInterface(Ci.nsIBinaryInputStream); - stream.setInputStream(rawStream); + stream.setInputStream(rawStream); - var bytes = stream.readByteArray(stream.available()); // returns int[] + var bytes = stream.readByteArray(stream.available()); // returns int[] - var base64String = toBase64(bytes); + var base64String = toBase64(bytes); - return "data:" + mimetype + ";base64," + base64String; + return "data:" + mimetype + ";base64," + base64String; } /* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */ /* Convert data (an array of integers) to a Base64 string. */ -const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + - '0123456789+/'; -const base64Pad = '='; +const toBase64Table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/"; +const base64Pad = "="; function toBase64(data) { - var result = ''; - var length = data.length; - var i; - // Convert every three bytes to 4 ascii characters. - for (i = 0; i < (length - 2); i += 3) { - result += toBase64Table[data[i] >> 2]; - result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; - result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)]; - result += toBase64Table[data[i+2] & 0x3f]; - } + var result = ""; + var length = data.length; + var i; + // Convert every three bytes to 4 ascii characters. + for (i = 0; i < length - 2; i += 3) { + result += toBase64Table[data[i] >> 2]; + result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; + result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; + result += toBase64Table[data[i + 2] & 0x3f]; + } - // Convert the remaining 1 or 2 bytes, pad out to 4 characters. - if (length%3) { - i = length - (length%3); - result += toBase64Table[data[i] >> 2]; - if ((length%3) == 2) { - result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; - result += toBase64Table[(data[i+1] & 0x0f) << 2]; - result += base64Pad; - } else { - result += toBase64Table[(data[i] & 0x03) << 4]; - result += base64Pad + base64Pad; - } + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. + if (length % 3) { + i = length - (length % 3); + result += toBase64Table[data[i] >> 2]; + if (length % 3 == 2) { + result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; + result += toBase64Table[(data[i + 1] & 0x0f) << 2]; + result += base64Pad; + } else { + result += toBase64Table[(data[i] & 0x03) << 4]; + result += base64Pad + base64Pad; } + } - return result; + return result; } diff --git a/image/test/unit/test_encoder_png.js b/image/test/unit/test_encoder_png.js index 1c719c4e5a0c..9b2020fc7927 100644 --- a/image/test/unit/test_encoder_png.js +++ b/image/test/unit/test_encoder_png.js @@ -4,250 +4,379 @@ */ var png1A = { - // A 3x3 image, rows are red, green, blue. - // RGB format, transparency defaults. + // A 3x3 image, rows are red, green, blue. + // RGB format, transparency defaults. - transparency : null, + transparency: null, - frames : [ - { - width : 3, height : 3, + frames: [ + { + width: 3, + height: 3, - format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9, + format: Ci.imgIEncoder.INPUT_FORMAT_RGB, + stride: 9, - pixels : [ - 255,0,0, 255,0,0, 255,0,0, - 0,255,0, 0,255,0, 0,255,0, - 0,0,255, 0,0,255, 0,0,255, - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=" + pixels: [ + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=", }; var png1B = { - // A 3x3 image, rows are red, green, blue. - // RGB format, transparency=none. + // A 3x3 image, rows are red, green, blue. + // RGB format, transparency=none. - transparency : "none", + transparency: "none", - frames : [ - { - width : 3, height : 3, + frames: [ + { + width: 3, + height: 3, - format : Ci.imgIEncoder.INPUT_FORMAT_RGB, stride : 9, + format: Ci.imgIEncoder.INPUT_FORMAT_RGB, + stride: 9, - pixels : [ - 255,0,0, 255,0,0, 255,0,0, - 0,255,0, 0,255,0, 0,255,0, - 0,0,255, 0,0,255, 0,0,255, - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=" + pixels: [ + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 0, + 255, + 0, + 0, + 255, + 0, + 0, + 255, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=", }; var png2A = { - // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent. + // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent. - transparency : null, + transparency: null, - frames : [ - { - width : 3, height : 3, + frames: [ + { + width: 3, + height: 3, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 255,0,0,255, 255,0,0,170, 255,0,0,85, - 0,255,0,255, 0,255,0,170, 0,255,0,85, - 0,0,255,255, 0,0,255,170, 0,0,255,85 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAIElEQVQImSXJMQEAMAwEIUy+yZi8DmVFFBcjycn86GgPJw4O8v9DkkEAAAAASUVORK5CYII=" + pixels: [ + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 170, + 255, + 0, + 0, + 85, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 170, + 0, + 255, + 0, + 85, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 170, + 0, + 0, + 255, + 85, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAIElEQVQImSXJMQEAMAwEIUy+yZi8DmVFFBcjycn86GgPJw4O8v9DkkEAAAAASUVORK5CYII=", }; var png2B = { - // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent, - // but transparency will be ignored. + // A 3x3 image, rows are: red, green, blue. Columns are: 0%, 33%, 66% transparent, + // but transparency will be ignored. - transparency : "none", + transparency: "none", - frames : [ - { - width : 3, height : 3, + frames: [ + { + width: 3, + height: 3, - format : Ci.imgIEncoder.INPUT_FORMAT_RGBA, stride : 12, + format: Ci.imgIEncoder.INPUT_FORMAT_RGBA, + stride: 12, - pixels : [ - 255,0,0,255, 255,0,0,170, 255,0,0,85, - 0,255,0,255, 0,255,0,170, 0,255,0,85, - 0,0,255,255, 0,0,255,170, 0,0,255,85 - ] - } - - ], - expected : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=" + pixels: [ + 255, + 0, + 0, + 255, + 255, + 0, + 0, + 170, + 255, + 0, + 0, + 85, + 0, + 255, + 0, + 255, + 0, + 255, + 0, + 170, + 0, + 255, + 0, + 85, + 0, + 0, + 255, + 255, + 0, + 0, + 255, + 170, + 0, + 0, + 255, + 85, + ], + }, + ], + expected: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=", }; // Main test entry point. function run_test() { - dump("Checking png1A...\n") - run_test_for(png1A); - dump("Checking png1B...\n") - run_test_for(png1B); - dump("Checking png2A...\n") - run_test_for(png2A); - dump("Checking png2B...\n") - run_test_for(png2B); -}; - + dump("Checking png1A...\n"); + run_test_for(png1A); + dump("Checking png1B...\n"); + run_test_for(png1B); + dump("Checking png2A...\n"); + run_test_for(png2A); + dump("Checking png2B...\n"); + run_test_for(png2B); +} function run_test_for(input) { - var encoder, dataURL; + var encoder, dataURL; - encoder = encodeImage(input); - dataURL = makeDataURL(encoder, "image/png"); - Assert.equal(dataURL, input.expected); - - encoder = encodeImageAsync(input); - dataURL = makeDataURLFromAsync(encoder, "image/png", input.expected); -}; + encoder = encodeImage(input); + dataURL = makeDataURL(encoder, "image/png"); + Assert.equal(dataURL, input.expected); + encoder = encodeImageAsync(input); + dataURL = makeDataURLFromAsync(encoder, "image/png", input.expected); +} function encodeImage(input) { - var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance(); - encoder.QueryInterface(Ci.imgIEncoder); + var encoder = Cc[ + "@mozilla.org/image/encoder;2?type=image/png" + ].createInstance(); + encoder.QueryInterface(Ci.imgIEncoder); - var options = ""; - if (input.transparency) { - options += "transparency=" + input.transparency; - } + var options = ""; + if (input.transparency) { + options += "transparency=" + input.transparency; + } - var frame = input.frames[0]; - encoder.initFromData(frame.pixels, frame.pixels.length, - frame.width, frame.height, frame.stride, - frame.format, options); - return encoder; + var frame = input.frames[0]; + encoder.initFromData( + frame.pixels, + frame.pixels.length, + frame.width, + frame.height, + frame.stride, + frame.format, + options + ); + return encoder; } -function _encodeImageAsyncFactory(frame, options, encoder) -{ - function finishEncode() { - encoder.addImageFrame(frame.pixels, frame.pixels.length, - frame.width, frame.height, frame.stride, - frame.format, options); - encoder.endImageEncode(); - } - return finishEncode; +function _encodeImageAsyncFactory(frame, options, encoder) { + function finishEncode() { + encoder.addImageFrame( + frame.pixels, + frame.pixels.length, + frame.width, + frame.height, + frame.stride, + frame.format, + options + ); + encoder.endImageEncode(); + } + return finishEncode; } -function encodeImageAsync(input) -{ - var encoder = Cc["@mozilla.org/image/encoder;2?type=image/png"].createInstance(); - encoder.QueryInterface(Ci.imgIEncoder); +function encodeImageAsync(input) { + var encoder = Cc[ + "@mozilla.org/image/encoder;2?type=image/png" + ].createInstance(); + encoder.QueryInterface(Ci.imgIEncoder); - var options = ""; - if (input.transparency) { - options += "transparency=" + input.transparency; - } + var options = ""; + if (input.transparency) { + options += "transparency=" + input.transparency; + } - var frame = input.frames[0]; - encoder.startImageEncode(frame.width, frame.height, - frame.format, options); + var frame = input.frames[0]; + encoder.startImageEncode(frame.width, frame.height, frame.format, options); - do_timeout(50, _encodeImageAsyncFactory(frame, options, encoder)); - return encoder; + do_timeout(50, _encodeImageAsyncFactory(frame, options, encoder)); + return encoder; } - function makeDataURL(encoder, mimetype) { - var rawStream = encoder.QueryInterface(Ci.nsIInputStream); + var rawStream = encoder.QueryInterface(Ci.nsIInputStream); - var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(); - stream.QueryInterface(Ci.nsIBinaryInputStream); + var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(); + stream.QueryInterface(Ci.nsIBinaryInputStream); - stream.setInputStream(rawStream); + stream.setInputStream(rawStream); - var bytes = stream.readByteArray(stream.available()); // returns int[] + var bytes = stream.readByteArray(stream.available()); // returns int[] - var base64String = toBase64(bytes); + var base64String = toBase64(bytes); - return "data:" + mimetype + ";base64," + base64String; + return "data:" + mimetype + ";base64," + base64String; } function makeDataURLFromAsync(encoder, mimetype, expected) { - do_test_pending(); - var rawStream = encoder.QueryInterface(Ci.nsIAsyncInputStream); + do_test_pending(); + var rawStream = encoder.QueryInterface(Ci.nsIAsyncInputStream); - var currentThread = Cc["@mozilla.org/thread-manager;1"].getService().currentThread; + var currentThread = Cc["@mozilla.org/thread-manager;1"].getService() + .currentThread; - var bytes = []; + var bytes = []; - var binarystream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(); - binarystream.QueryInterface(Ci.nsIBinaryInputStream); + var binarystream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(); + binarystream.QueryInterface(Ci.nsIBinaryInputStream); - var asyncReader = - { - onInputStreamReady(stream) - { - binarystream.setInputStream(stream); - var available = 0; - try { - available = stream.available(); - } catch(e) { } + var asyncReader = { + onInputStreamReady(stream) { + binarystream.setInputStream(stream); + var available = 0; + try { + available = stream.available(); + } catch (e) {} - if (available > 0) - { - bytes = bytes.concat(binarystream.readByteArray(available)); - stream.asyncWait(this, 0, 0, currentThread); - } else { - var base64String = toBase64(bytes); - var dataURL = "data:" + mimetype + ";base64," + base64String; - Assert.equal(dataURL, expected); - do_test_finished(); - } - - } - }; - rawStream.asyncWait(asyncReader, 0, 0, currentThread); + if (available > 0) { + bytes = bytes.concat(binarystream.readByteArray(available)); + stream.asyncWait(this, 0, 0, currentThread); + } else { + var base64String = toBase64(bytes); + var dataURL = "data:" + mimetype + ";base64," + base64String; + Assert.equal(dataURL, expected); + do_test_finished(); + } + }, + }; + rawStream.asyncWait(asyncReader, 0, 0, currentThread); } /* toBase64 copied from extensions/xml-rpc/src/nsXmlRpcClient.js */ /* Convert data (an array of integers) to a Base64 string. */ -const toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + - '0123456789+/'; -const base64Pad = '='; +const toBase64Table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/"; +const base64Pad = "="; function toBase64(data) { - var result = ''; - var length = data.length; - var i; - // Convert every three bytes to 4 ascii characters. - for (i = 0; i < (length - 2); i += 3) { - result += toBase64Table[data[i] >> 2]; - result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; - result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)]; - result += toBase64Table[data[i+2] & 0x3f]; - } + var result = ""; + var length = data.length; + var i; + // Convert every three bytes to 4 ascii characters. + for (i = 0; i < length - 2; i += 3) { + result += toBase64Table[data[i] >> 2]; + result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; + result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; + result += toBase64Table[data[i + 2] & 0x3f]; + } - // Convert the remaining 1 or 2 bytes, pad out to 4 characters. - if (length%3) { - i = length - (length%3); - result += toBase64Table[data[i] >> 2]; - if ((length%3) == 2) { - result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; - result += toBase64Table[(data[i+1] & 0x0f) << 2]; - result += base64Pad; - } else { - result += toBase64Table[(data[i] & 0x03) << 4]; - result += base64Pad + base64Pad; - } + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. + if (length % 3) { + i = length - (length % 3); + result += toBase64Table[data[i] >> 2]; + if (length % 3 == 2) { + result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; + result += toBase64Table[(data[i + 1] & 0x0f) << 2]; + result += base64Pad; + } else { + result += toBase64Table[(data[i] & 0x03) << 4]; + result += base64Pad + base64Pad; } + } - return result; + return result; } diff --git a/image/test/unit/test_imgtools.js b/image/test/unit/test_imgtools.js index fc854954211c..2b72700633d2 100644 --- a/image/test/unit/test_imgtools.js +++ b/image/test/unit/test_imgtools.js @@ -2,7 +2,7 @@ * Tests for imgITools */ -const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); /* * dumpToFile() @@ -11,732 +11,787 @@ const {NetUtil} = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); * Call |dumpToFile(outData);| in a test to file to a file. */ function dumpToFile(aData) { - var outputFile = do_get_tempdir(); - outputFile.append("testdump.png"); + var outputFile = do_get_tempdir(); + outputFile.append("testdump.png"); - var outputStream = Cc["@mozilla.org/network/file-output-stream;1"]. - createInstance(Ci.nsIFileOutputStream); - // WR_ONLY|CREAT|TRUNC - outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null); + var outputStream = Cc[ + "@mozilla.org/network/file-output-stream;1" + ].createInstance(Ci.nsIFileOutputStream); + // WR_ONLY|CREAT|TRUNC + outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null); - var bos = Cc["@mozilla.org/binaryoutputstream;1"]. - createInstance(Ci.nsIBinaryOutputStream); - bos.setOutputStream(outputStream); + var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance( + Ci.nsIBinaryOutputStream + ); + bos.setOutputStream(outputStream); - bos.writeByteArray(aData, aData.length); + bos.writeByteArray(aData, aData.length); - outputStream.close(); + outputStream.close(); } - /* * getFileInputStream() * * Returns an input stream for the specified file. */ function getFileInputStream(aFile) { - var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); - // init the stream as RD_ONLY, -1 == default permissions. - inputStream.init(aFile, 0x01, -1, null); + var inputStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + // init the stream as RD_ONLY, -1 == default permissions. + inputStream.init(aFile, 0x01, -1, null); - // Blah. The image decoders use ReadSegments, which isn't implemented on - // file input streams. Use a buffered stream to make it work. - var bis = Cc["@mozilla.org/network/buffered-input-stream;1"]. - createInstance(Ci.nsIBufferedInputStream); - bis.init(inputStream, 1024); + // Blah. The image decoders use ReadSegments, which isn't implemented on + // file input streams. Use a buffered stream to make it work. + var bis = Cc["@mozilla.org/network/buffered-input-stream;1"].createInstance( + Ci.nsIBufferedInputStream + ); + bis.init(inputStream, 1024); - return bis; + return bis; } - /* * streamToArray() * * Consumes an input stream, and returns its bytes as an array. */ function streamToArray(aStream) { - var size = aStream.available(); + var size = aStream.available(); - // use a binary input stream to grab the bytes. - var bis = Cc["@mozilla.org/binaryinputstream;1"]. - createInstance(Ci.nsIBinaryInputStream); - bis.setInputStream(aStream); + // use a binary input stream to grab the bytes. + var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance( + Ci.nsIBinaryInputStream + ); + bis.setInputStream(aStream); - var bytes = bis.readByteArray(size); - if (size != bytes.length) - throw "Didn't read expected number of bytes"; + var bytes = bis.readByteArray(size); + if (size != bytes.length) { + throw "Didn't read expected number of bytes"; + } - return bytes; + return bytes; } - /* * compareArrays * * Compares two arrays, and throws if there's a difference. */ function compareArrays(aArray1, aArray2) { - Assert.equal(aArray1.length, aArray2.length); + Assert.equal(aArray1.length, aArray2.length); - for (var i = 0; i < aArray1.length; i++) - if (aArray1[i] != aArray2[i]) - throw "arrays differ at index " + i; + for (var i = 0; i < aArray1.length; i++) { + if (aArray1[i] != aArray2[i]) { + throw "arrays differ at index " + i; + } + } } - /* * checkExpectedError * * Checks to see if a thrown error was expected or not, and if it * matches the expected value. */ -function checkExpectedError (aExpectedError, aActualError) { +function checkExpectedError(aExpectedError, aActualError) { if (aExpectedError) { - if (!aActualError) - throw "Didn't throw as expected (" + aExpectedError + ")"; + if (!aActualError) { + throw "Didn't throw as expected (" + aExpectedError + ")"; + } - if (!aExpectedError.test(aActualError)) - throw "Threw (" + aActualError + "), not (" + aExpectedError; + if (!aExpectedError.test(aActualError)) { + throw "Threw (" + aActualError + "), not (" + aExpectedError; + } - // We got the expected error, so make a note in the test log. - dump("...that error was expected.\n\n"); + // We got the expected error, so make a note in the test log. + dump("...that error was expected.\n\n"); } else if (aActualError) { - throw "Threw unexpected error: " + aActualError; + throw "Threw unexpected error: " + aActualError; } } - function run_test() { + try { + /* ========== 0 ========== */ + var testnum = 0; + var testdesc = "imgITools setup"; + var err = null; + + var imgTools = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools); + + if (!imgTools) { + throw "Couldn't get imgITools service"; + } + + // Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes + // +/- 1 value compared to other platforms, so we need to compare against a + // different set of reference images. nsIXULRuntime.OS doesn't seem to be + // available in xpcshell, so we'll use this as a kludgy way to figure out if + // we're running on Windows. + var isWindows = mozinfo.os == "win"; + + /* ========== 1 ========== */ + testnum++; + testdesc = "test decoding a PNG"; + + // 64x64 png, 8415 bytes. + var imgName = "image1.png"; + var inMimeType = "image/png"; + var imgFile = do_get_file(imgName); -try { - - -/* ========== 0 ========== */ -var testnum = 0; -var testdesc = "imgITools setup"; -var err = null; - -var imgTools = Cc["@mozilla.org/image/tools;1"]. - getService(Ci.imgITools); - -if (!imgTools) - throw "Couldn't get imgITools service" - -// Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes -// +/- 1 value compared to other platforms, so we need to compare against a -// different set of reference images. nsIXULRuntime.OS doesn't seem to be -// available in xpcshell, so we'll use this as a kludgy way to figure out if -// we're running on Windows. -var isWindows = mozinfo.os == "win"; - - -/* ========== 1 ========== */ -testnum++; -testdesc = "test decoding a PNG"; - -// 64x64 png, 8415 bytes. -var imgName = "image1.png"; -var inMimeType = "image/png"; -var imgFile = do_get_file(imgName); - -var istream = getFileInputStream(imgFile); -Assert.equal(istream.available(), 8415); - -var buffer = NetUtil.readInputStreamToString(istream, istream.available()); -var container = imgTools.decodeImageFromBuffer(buffer, buffer.length, - inMimeType); - -// It's not easy to look at the pixel values from JS, so just -// check the container's size. -Assert.equal(container.width, 64); -Assert.equal(container.height, 64); - - -/* ========== 2 ========== */ -testnum++; -testdesc = "test encoding a scaled JPEG"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 16); - -var encodedBytes = streamToArray(istream); -// Get bytes for exected result -var refName = "image1png16x16.jpg"; -var refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1051); -var referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 3 ========== */ -testnum++; -testdesc = "test encoding an unscaled JPEG"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeImage(container, "image/jpeg"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image1png64x64.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 4503); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 4 ========== */ -testnum++; -testdesc = "test decoding a JPEG"; - -// 32x32 jpeg, 3494 bytes. -imgName = "image2.jpg"; -inMimeType = "image/jpeg"; -imgFile = do_get_file(imgName); - -istream = getFileInputStream(imgFile); -Assert.equal(istream.available(), 3494); - -buffer = NetUtil.readInputStreamToString(istream, istream.available()); -container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType); - -// It's not easy to look at the pixel values from JS, so just -// check the container's size. -Assert.equal(container.width, 32); -Assert.equal(container.height, 32); - - -/* ========== 5 ========== */ -testnum++; -testdesc = "test encoding a scaled PNG"; - -if (!isWindows) { -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, "image/png", 16, 16); - -encodedBytes = streamToArray(istream); -// Get bytes for exected result -refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 950); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); -} - - -/* ========== 6 ========== */ -testnum++; -testdesc = "test encoding an unscaled PNG"; - -if (!isWindows) { -// we'll reuse the container from the previous test -istream = imgTools.encodeImage(container, "image/png"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = isWindows ? "image2jpg32x32-win.png" : "image2jpg32x32.png"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 3105); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); -} - - -/* ========== 7 ========== */ -testnum++; -testdesc = "test decoding a ICO"; - -// 16x16 ico, 1406 bytes. -imgName = "image3.ico"; -inMimeType = "image/x-icon"; -imgFile = do_get_file(imgName); - -istream = getFileInputStream(imgFile); -Assert.equal(istream.available(), 1406); - -buffer = NetUtil.readInputStreamToString(istream, istream.available()); -container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType); - -// It's not easy to look at the pixel values from JS, so just -// check the container's size. -Assert.equal(container.width, 16); -Assert.equal(container.height, 16); - - -/* ========== 8 ========== */ -testnum++; -testdesc = "test encoding a scaled PNG"; // note that we're scaling UP - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, "image/png", 32, 32); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image3ico32x32.png"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 2285); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 9 ========== */ -testnum++; -testdesc = "test encoding an unscaled PNG"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeImage(container, "image/png"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image3ico16x16.png"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 330); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 10 ========== */ -testnum++; -testdesc = "test decoding a GIF"; - -// 32x32 gif, 1809 bytes. -imgName = "image4.gif"; -inMimeType = "image/gif"; -imgFile = do_get_file(imgName); - -istream = getFileInputStream(imgFile); -Assert.equal(istream.available(), 1809); - -buffer = NetUtil.readInputStreamToString(istream, istream.available()); -container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType); - -// It's not easy to look at the pixel values from JS, so just -// check the container's size. -Assert.equal(container.width, 32); -Assert.equal(container.height, 32); - -/* ========== 11 ========== */ -testnum++; -testdesc = "test encoding an unscaled ICO with format options " + - "(format=bmp;bpp=32)"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeImage(container, - "image/vnd.microsoft.icon", - "format=bmp;bpp=32"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image4gif32x32bmp32bpp.ico"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 4286); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - -/* ========== 12 ========== */ -testnum++; -testdesc = "test encoding a scaled ICO with format options " + - "(format=bmp;bpp=32)"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, - "image/vnd.microsoft.icon", - 16, - 16, - "format=bmp;bpp=32"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image4gif16x16bmp32bpp.ico"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1150); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - -/* ========== 13 ========== */ -testnum++; -testdesc = "test encoding an unscaled ICO with format options " + - "(format=bmp;bpp=24)"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeImage(container, - "image/vnd.microsoft.icon", - "format=bmp;bpp=24"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image4gif32x32bmp24bpp.ico"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 3262); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - -/* ========== 14 ========== */ -testnum++; -testdesc = "test encoding a scaled ICO with format options " + - "(format=bmp;bpp=24)"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, - "image/vnd.microsoft.icon", - 16, - 16, - "format=bmp;bpp=24"); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image4gif16x16bmp24bpp.ico"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 894); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 15 ========== */ -testnum++; -testdesc = "test cropping a JPG"; - -// 32x32 jpeg, 3494 bytes. -imgName = "image2.jpg"; -inMimeType = "image/jpeg"; -imgFile = do_get_file(imgName); - -istream = getFileInputStream(imgFile); -Assert.equal(istream.available(), 3494); - -buffer = NetUtil.readInputStreamToString(istream, istream.available()); -container = imgTools.decodeImageFromBuffer(buffer, buffer.length, inMimeType); - -// It's not easy to look at the pixel values from JS, so just -// check the container's size. -Assert.equal(container.width, 32); -Assert.equal(container.height, 32); - -// encode a cropped image -istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 16); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg16x16cropped.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 879); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 16 ========== */ -testnum++; -testdesc = "test cropping a JPG with an offset"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeCroppedImage(container, "image/jpeg", 16, 16, 16, 16); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg16x16cropped2.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 878); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 17 ========== */ -testnum++; -testdesc = "test cropping a JPG without a given height"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 0); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg16x32cropped3.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1127); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 18 ========== */ -testnum++; -testdesc = "test cropping a JPG without a given width"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 16); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg32x16cropped4.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1135); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 19 ========== */ -testnum++; -testdesc = "test cropping a JPG without a given width and height"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 0); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg32x32.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1634); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 20 ========== */ -testnum++; -testdesc = "test scaling a JPG without a given width"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 16); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg32x16scaled.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1227); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 21 ========== */ -testnum++; -testdesc = "test scaling a JPG without a given height"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 0); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg16x32scaled.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1219); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 22 ========== */ -testnum++; -testdesc = "test scaling a JPG without a given width and height"; - -// we'll reuse the container from the previous test -istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 0); -encodedBytes = streamToArray(istream); - -// Get bytes for exected result -refName = "image2jpg32x32.jpg"; -refFile = do_get_file(refName); -istream = getFileInputStream(refFile); -Assert.equal(istream.available(), 1634); -referenceBytes = streamToArray(istream); - -// compare the encoder's output to the reference file. -compareArrays(encodedBytes, referenceBytes); - - -/* ========== 22 ========== */ -testnum++; -testdesc = "test invalid arguments for cropping"; - -var numErrors = 0; - -try { - // width/height can't be negative - imgTools.encodeScaledImage(container, "image/jpeg", -1, -1); -} catch (e) { numErrors++; } - -try { - // offsets can't be negative - imgTools.encodeCroppedImage(container, "image/jpeg", -1, -1, 16, 16); -} catch (e) { numErrors++; } - -try { - // width/height can't be negative - imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, -1, -1); -} catch (e) { numErrors++; } - -try { - // out of bounds - imgTools.encodeCroppedImage(container, "image/jpeg", 17, 17, 16, 16); -} catch (e) { numErrors++; } - -try { - // out of bounds - imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 33, 33); -} catch (e) { numErrors++; } - -try { - // out of bounds - imgTools.encodeCroppedImage(container, "image/jpeg", 1, 1, 0, 0); -} catch (e) { numErrors++; } - -Assert.equal(numErrors, 6); - - -/* ========== bug 363986 ========== */ -testnum = 363986; -testdesc = "test PNG and JPEG encoders' Read/ReadSegments methods"; - -var testData = - [{preImage: "image3.ico", - preImageMimeType: "image/x-icon", - refImage: "image3ico16x16.png", - refImageMimeType: "image/png"}, - {preImage: "image1.png", - preImageMimeType: "image/png", - refImage: "image1png64x64.jpg", - refImageMimeType: "image/jpeg"}]; - -for(var i=0; i