123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- /*
- * Tests for imgITools
- */
- var Ci = Components.interfaces;
- var Cc = Components.classes;
- /*
- * dumpToFile()
- *
- * For test development, dumps the specified array to a file.
- * Call |dumpToFile(outData);| in a test to file to a file.
- */
- function dumpToFile(aData) {
- 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 bos = Cc["@mozilla.org/binaryoutputstream;1"].
- createInstance(Ci.nsIBinaryOutputStream);
- bos.setOutputStream(outputStream);
- bos.writeByteArray(aData, aData.length);
- 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 "Didn't read expected number of bytes";
- return bytes;
- }
- /*
- * compareArrays
- *
- * Compares two arrays, and throws if there's a difference.
- */
- function compareArrays(aArray1, aArray2) {
- do_check_eq(aArray1.length, aArray2.length);
- 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) {
- if (aExpectedError) {
- if (!aActualError)
- throw "Didn't throw as expected (" + 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");
- } else if (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);
- var istream = getFileInputStream(imgFile);
- do_check_eq(istream.available(), 8415);
- // Use decodeImageData for this test even though it's deprecated to ensure that
- // it correctly forwards to decodeImage and continues to work.
- var outParam = { value: null };
- imgTools.decodeImageData(istream, inMimeType, outParam);
- var container = outParam.value;
- // It's not easy to look at the pixel values from JS, so just
- // check the container's size.
- do_check_eq(container.width, 64);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(istream.available(), 3494);
- container = imgTools.decodeImage(istream, inMimeType);
- // It's not easy to look at the pixel values from JS, so just
- // check the container's size.
- do_check_eq(container.width, 32);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(istream.available(), 1406);
- container = imgTools.decodeImage(istream, inMimeType);
- // It's not easy to look at the pixel values from JS, so just
- // check the container's size.
- do_check_eq(container.width, 16);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(istream.available(), 1809);
- container = imgTools.decodeImage(istream, inMimeType);
- // It's not easy to look at the pixel values from JS, so just
- // check the container's size.
- do_check_eq(container.width, 32);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(istream.available(), 3494);
- container = imgTools.decodeImage(istream, inMimeType);
- // It's not easy to look at the pixel values from JS, so just
- // check the container's size.
- do_check_eq(container.width, 32);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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);
- do_check_eq(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++; }
- do_check_eq(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<testData.length; ++i) {
- var dict = testData[i];
- var imgFile = do_get_file(dict["refImage"]);
- var istream = getFileInputStream(imgFile);
- var refBytes = streamToArray(istream);
- imgFile = do_get_file(dict["preImage"]);
- istream = getFileInputStream(imgFile);
- var container = imgTools.decodeImage(istream, 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);
- do_check_eq(istream.available(), 17759);
- var errsrc = "none";
- try {
- container = imgTools.decodeImage(istream, 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 decodeImage()
- // 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";
- }
- do_check_eq(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);
- do_check_eq(istream.available(), 4286);
- container = imgTools.decodeImage(istream, inMimeType);
- var props = container.QueryInterface(Ci.nsIProperties);
- do_check_eq(props.get("hotspotX", Ci.nsISupportsPRUint32).data, 10);
- do_check_eq(props.get("hotspotY", Ci.nsISupportsPRUint32).data, 9);
- /* ========== end ========== */
- } catch (e) {
- throw "FAILED in test #" + testnum + " -- " + testdesc + ": " + e;
- }
- };
|