summaryrefslogtreecommitdiffstats
path: root/image/test/unit/test_imgtools.js
diff options
context:
space:
mode:
Diffstat (limited to 'image/test/unit/test_imgtools.js')
-rw-r--r--image/test/unit/test_imgtools.js871
1 files changed, 871 insertions, 0 deletions
diff --git a/image/test/unit/test_imgtools.js b/image/test/unit/test_imgtools.js
new file mode 100644
index 0000000000..689a4ed56f
--- /dev/null
+++ b/image/test/unit/test_imgtools.js
@@ -0,0 +1,871 @@
+/*
+ * Tests for imgITools
+ */
+
+const { NetUtil } = ChromeUtils.importESModule(
+ "resource://gre/modules/NetUtil.sys.mjs"
+);
+
+/*
+ * dumpToFile()
+ *
+ * For test development, dumps the specified array to a file.
+ * Call |dumpToFile(outData);| in a test to file to a file.
+ */
+// eslint-disable-next-line no-unused-vars
+function dumpToFile(aData) {
+ var outputFile = do_get_cwd();
+ outputFile.append("testdump.webp");
+
+ var outputStream = Cc[
+ "@mozilla.org/network/file-output-stream;1"
+ ].createInstance(Ci.nsIFileOutputStream);
+ // WR_ONLY|CREATE|TRUNC
+ outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null);
+
+ var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(
+ Ci.nsIBinaryOutputStream
+ );
+ bos.setOutputStream(outputStream);
+
+ bos.writeByteArray(aData);
+
+ 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);
+
+ // 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;
+}
+
+/*
+ * streamToArray()
+ *
+ * Consumes an input stream, and returns its bytes as an array.
+ */
+function streamToArray(aStream) {
+ 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);
+
+ var bytes = bis.readByteArray(size);
+ if (size != bytes.length) {
+ throw new Error("Didn't read expected number of bytes");
+ }
+
+ return bytes;
+}
+
+/*
+ * compareArrays
+ *
+ * Compares two arrays, and throws if there's a difference.
+ */
+function compareArrays(aArray1, aArray2) {
+ Assert.equal(aArray1.length, aArray2.length);
+
+ for (var i = 0; i < aArray1.length; i++) {
+ if (aArray1[i] != aArray2[i]) {
+ throw new Error("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) {
+ if (aExpectedError) {
+ if (!aActualError) {
+ throw new Error("Didn't throw as expected (" + aExpectedError + ")");
+ }
+
+ if (!aExpectedError.test(aActualError)) {
+ throw new Error("Threw (" + aActualError + "), not (" + aExpectedError);
+ }
+
+ // We got the expected error, so make a note in the test log.
+ dump("...that error was expected.\n\n");
+ } else if (aActualError) {
+ throw new Error("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 new Error("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 expected result
+ var refName = "image1png16x16.jpg";
+ var refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1050);
+ 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 expected result
+ refName = "image1png64x64.jpg";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 4507);
+ 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 expected result
+ refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 955);
+ 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 expected result
+ refName = isWindows ? "image2jpg32x32-win.png" : "image2jpg32x32.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 3026);
+ 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 expected result
+ refName = "image3ico32x32.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 2280);
+ 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 expected result
+ refName = "image3ico16x16.png";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 520);
+ 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 expected 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 =
+ // eslint-disable-next-line no-useless-concat
+ "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 expected 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 expected 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 =
+ // eslint-disable-next-line no-useless-concat
+ "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 expected 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 expected 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 expected 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 expected 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 expected 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 expected 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 expected 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 expected 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 expected 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);
+
+ /* ========== 23 ========== */
+ 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);
+
+ /* ========== 24 ========== */
+ testnum++;
+ testdesc = "test encoding webp";
+
+ // Load picture that we want to convert
+ imgName = "image1.png";
+ inMimeType = "image/png";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 8415);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // Convert image to webp
+ istream = imgTools.encodeImage(container, "image/webp");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image1.webp";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 3206);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== 25 ========== */
+ testnum++;
+ testdesc = "test encoding webp with quality parameter";
+
+ // Load picture that we want to convert
+ imgName = "image1.png";
+ inMimeType = "image/png";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 8415);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // Convert image to webp
+ istream = imgTools.encodeImage(container, "image/webp", "quality=50");
+ encodedBytes = streamToArray(istream);
+
+ // Get bytes for expected result
+ refName = "image1quality50.webp";
+ refFile = do_get_file(refName);
+ istream = getFileInputStream(refFile);
+ Assert.equal(istream.available(), 1944);
+ referenceBytes = streamToArray(istream);
+
+ // compare the encoder's output to the reference file.
+ compareArrays(encodedBytes, referenceBytes);
+
+ /* ========== bug 363986 ========== */
+ testnum = 363986;
+ testdesc = "test PNG and JPEG and WEBP 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",
+ },
+ {
+ preImage: "image1.png",
+ preImageMimeType: "image/png",
+ refImage: "image1.webp",
+ refImageMimeType: "image/webp",
+ },
+ ];
+
+ for (var i = 0; i < testData.length; ++i) {
+ var dict = testData[i];
+
+ imgFile = do_get_file(dict.refImage);
+ istream = getFileInputStream(imgFile);
+ var refBytes = streamToArray(istream);
+
+ imgFile = do_get_file(dict.preImage);
+ istream = getFileInputStream(imgFile);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ dict.preImageMimeType
+ );
+
+ istream = imgTools.encodeImage(container, dict.refImageMimeType);
+
+ var sstream = Cc["@mozilla.org/storagestream;1"].createInstance(
+ Ci.nsIStorageStream
+ );
+ sstream.init(4096, 4294967295, null);
+ var ostream = sstream.getOutputStream(0);
+ var bostream = Cc[
+ "@mozilla.org/network/buffered-output-stream;1"
+ ].createInstance(Ci.nsIBufferedOutputStream);
+
+ // use a tiny buffer to make sure the image data doesn't fully fit in it
+ bostream.init(ostream, 8);
+
+ bostream.writeFrom(istream, istream.available());
+ bostream.flush();
+ bostream.close();
+
+ var encBytes = streamToArray(sstream.newInputStream(0));
+
+ compareArrays(refBytes, encBytes);
+ }
+
+ /* ========== bug 413512 ========== */
+ testnum = 413512;
+ testdesc = "test decoding bad favicon (bug 413512)";
+
+ imgName = "bug413512.ico";
+ inMimeType = "image/x-icon";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 17759);
+ var errsrc = "none";
+
+ try {
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ // We expect to hit an error during encoding because the ICO header of the
+ // image is fine, but the actual resources are corrupt. Since
+ // decodeImageFromBuffer() only performs a metadata decode, it doesn't decode
+ // far enough to realize this, but we'll find out when we do a full decode
+ // during encodeImage().
+ try {
+ istream = imgTools.encodeImage(container, "image/png");
+ } catch (e) {
+ err = e;
+ errsrc = "encode";
+ }
+ } catch (e) {
+ err = e;
+ errsrc = "decode";
+ }
+
+ Assert.equal(errsrc, "encode");
+ checkExpectedError(/NS_ERROR_FAILURE/, err);
+
+ /* ========== bug 815359 ========== */
+ testnum = 815359;
+ testdesc = "test correct ico hotspots (bug 815359)";
+
+ imgName = "bug815359.ico";
+ inMimeType = "image/x-icon";
+ imgFile = do_get_file(imgName);
+
+ istream = getFileInputStream(imgFile);
+ Assert.equal(istream.available(), 4286);
+
+ buffer = NetUtil.readInputStreamToString(istream, istream.available());
+ container = imgTools.decodeImageFromBuffer(
+ buffer,
+ buffer.length,
+ inMimeType
+ );
+
+ Assert.equal(container.hotspotX, 10);
+ Assert.equal(container.hotspotY, 9);
+
+ /* ========== end ========== */
+ } catch (e) {
+ throw new Error(
+ "FAILED in test #" + testnum + " -- " + testdesc + ": " + e
+ );
+ }
+}