tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_imgtools.js (26803B)


      1 /*
      2 * Tests for imgITools
      3 */
      4 
      5 const { NetUtil } = ChromeUtils.importESModule(
      6  "resource://gre/modules/NetUtil.sys.mjs"
      7 );
      8 const { AppConstants } = ChromeUtils.importESModule(
      9  "resource://gre/modules/AppConstants.sys.mjs"
     10 );
     11 
     12 /*
     13 * dumpToFile()
     14 *
     15 * For test development, dumps the specified array to a file.
     16 * Call |dumpToFile(outData);| in a test to file to a file.
     17 */
     18 // eslint-disable-next-line no-unused-vars
     19 function dumpToFile(aData) {
     20  var outputFile = do_get_cwd();
     21  outputFile.append("testdump.webp");
     22 
     23  var outputStream = Cc[
     24    "@mozilla.org/network/file-output-stream;1"
     25  ].createInstance(Ci.nsIFileOutputStream);
     26  // WR_ONLY|CREATE|TRUNC
     27  outputStream.init(outputFile, 0x02 | 0x08 | 0x20, 0o644, null);
     28 
     29  var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(
     30    Ci.nsIBinaryOutputStream
     31  );
     32  bos.setOutputStream(outputStream);
     33 
     34  bos.writeByteArray(aData);
     35 
     36  outputStream.close();
     37 }
     38 
     39 /*
     40 * getFileInputStream()
     41 *
     42 * Returns an input stream for the specified file.
     43 */
     44 function getFileInputStream(aFile) {
     45  var inputStream = Cc[
     46    "@mozilla.org/network/file-input-stream;1"
     47  ].createInstance(Ci.nsIFileInputStream);
     48  // init the stream as RD_ONLY, -1 == default permissions.
     49  inputStream.init(aFile, 0x01, -1, null);
     50 
     51  // Blah. The image decoders use ReadSegments, which isn't implemented on
     52  // file input streams. Use a buffered stream to make it work.
     53  var bis = Cc["@mozilla.org/network/buffered-input-stream;1"].createInstance(
     54    Ci.nsIBufferedInputStream
     55  );
     56  bis.init(inputStream, 1024);
     57 
     58  return bis;
     59 }
     60 
     61 /*
     62 * streamToArray()
     63 *
     64 * Consumes an input stream, and returns its bytes as an array.
     65 */
     66 function streamToArray(aStream) {
     67  var size = aStream.available();
     68 
     69  // use a binary input stream to grab the bytes.
     70  var bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
     71    Ci.nsIBinaryInputStream
     72  );
     73  bis.setInputStream(aStream);
     74 
     75  var bytes = bis.readByteArray(size);
     76  if (size != bytes.length) {
     77    throw new Error("Didn't read expected number of bytes");
     78  }
     79 
     80  return bytes;
     81 }
     82 
     83 /*
     84 * compareArrays
     85 *
     86 * Compares two arrays, and throws if there's a difference.
     87 */
     88 function compareArrays(aArray1, aArray2) {
     89  Assert.equal(aArray1.length, aArray2.length);
     90 
     91  for (var i = 0; i < aArray1.length; i++) {
     92    if (aArray1[i] != aArray2[i]) {
     93      throw new Error("arrays differ at index " + i);
     94    }
     95  }
     96 }
     97 
     98 /*
     99 * checkExpectedError
    100 *
    101 * Checks to see if a thrown error was expected or not, and if it
    102 * matches the expected value.
    103 */
    104 function checkExpectedError(aExpectedError, aActualError) {
    105  if (aExpectedError) {
    106    if (!aActualError) {
    107      throw new Error("Didn't throw as expected (" + aExpectedError + ")");
    108    }
    109 
    110    if (!aExpectedError.test(aActualError)) {
    111      throw new Error("Threw (" + aActualError + "), not (" + aExpectedError);
    112    }
    113 
    114    // We got the expected error, so make a note in the test log.
    115    dump("...that error was expected.\n\n");
    116  } else if (aActualError) {
    117    throw new Error("Threw unexpected error: " + aActualError);
    118  }
    119 }
    120 
    121 function run_test() {
    122  try {
    123    /* ========== 0 ========== */
    124    var testnum = 0;
    125    var testdesc = "imgITools setup";
    126    var err = null;
    127 
    128    var imgTools = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools);
    129 
    130    if (!imgTools) {
    131      throw new Error("Couldn't get imgITools service");
    132    }
    133 
    134    // Ugh, this is an ugly hack. The pixel values we get in Windows are sometimes
    135    // +/- 1 value compared to other platforms, so we need to compare against a
    136    // different set of reference images. nsIXULRuntime.OS doesn't seem to be
    137    // available in xpcshell, so we'll use this as a kludgy way to figure out if
    138    // we're running on Windows.
    139    var isWindows = mozinfo.os == "win";
    140 
    141    /* ========== 1 ========== */
    142    testnum++;
    143    testdesc = "test decoding a PNG";
    144 
    145    // 64x64 png, 8415 bytes.
    146    var imgName = "image1.png";
    147    var inMimeType = "image/png";
    148    var imgFile = do_get_file(imgName);
    149 
    150    var istream = getFileInputStream(imgFile);
    151    Assert.equal(istream.available(), 8415);
    152 
    153    var buffer = NetUtil.readInputStreamToString(istream, istream.available());
    154    var container = imgTools.decodeImageFromBuffer(
    155      buffer,
    156      buffer.length,
    157      inMimeType
    158    );
    159 
    160    // It's not easy to look at the pixel values from JS, so just
    161    // check the container's size.
    162    Assert.equal(container.width, 64);
    163    Assert.equal(container.height, 64);
    164 
    165    /* ========== 2 ========== */
    166    testnum++;
    167    testdesc = "test encoding a scaled JPEG";
    168 
    169    // we'll reuse the container from the previous test
    170    istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 16);
    171 
    172    var encodedBytes = streamToArray(istream);
    173    // Get bytes for expected result
    174    var refName = "image1png16x16.jpg";
    175    var refFile = do_get_file(refName);
    176    istream = getFileInputStream(refFile);
    177    Assert.equal(istream.available(), 1050);
    178    var referenceBytes = streamToArray(istream);
    179 
    180    // compare the encoder's output to the reference file.
    181    compareArrays(encodedBytes, referenceBytes);
    182 
    183    /* ========== 3 ========== */
    184    testnum++;
    185    testdesc = "test encoding an unscaled JPEG";
    186 
    187    // we'll reuse the container from the previous test
    188    istream = imgTools.encodeImage(container, "image/jpeg");
    189    encodedBytes = streamToArray(istream);
    190 
    191    // Get bytes for expected result
    192    refName = "image1png64x64.jpg";
    193    refFile = do_get_file(refName);
    194    istream = getFileInputStream(refFile);
    195    Assert.equal(istream.available(), 4507);
    196    referenceBytes = streamToArray(istream);
    197 
    198    // compare the encoder's output to the reference file.
    199    compareArrays(encodedBytes, referenceBytes);
    200 
    201    /* ========== 4 ========== */
    202    testnum++;
    203    testdesc = "test decoding a JPEG";
    204 
    205    // 32x32 jpeg, 3494 bytes.
    206    imgName = "image2.jpg";
    207    inMimeType = "image/jpeg";
    208    imgFile = do_get_file(imgName);
    209 
    210    istream = getFileInputStream(imgFile);
    211    Assert.equal(istream.available(), 3494);
    212 
    213    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    214    container = imgTools.decodeImageFromBuffer(
    215      buffer,
    216      buffer.length,
    217      inMimeType
    218    );
    219 
    220    // It's not easy to look at the pixel values from JS, so just
    221    // check the container's size.
    222    Assert.equal(container.width, 32);
    223    Assert.equal(container.height, 32);
    224 
    225    /* ========== 5 ========== */
    226    testnum++;
    227    testdesc = "test encoding a scaled PNG";
    228 
    229    if (!isWindows) {
    230      // we'll reuse the container from the previous test
    231      istream = imgTools.encodeScaledImage(container, "image/png", 16, 16);
    232 
    233      encodedBytes = streamToArray(istream);
    234      // Get bytes for expected result
    235      if (AppConstants.USE_LIBZ_RS) {
    236        refName = "image2jpg16x16.libz-rs.png";
    237      } else {
    238        refName = isWindows ? "image2jpg16x16-win.png" : "image2jpg16x16.png";
    239      }
    240      refFile = do_get_file(refName);
    241      istream = getFileInputStream(refFile);
    242      Assert.equal(istream.available(), AppConstants.USE_LIBZ_RS ? 941 : 955);
    243      referenceBytes = streamToArray(istream);
    244 
    245      // compare the encoder's output to the reference file.
    246      compareArrays(encodedBytes, referenceBytes);
    247    }
    248 
    249    /* ========== 6 ========== */
    250    testnum++;
    251    testdesc = "test encoding an unscaled PNG";
    252 
    253    if (!isWindows) {
    254      // we'll reuse the container from the previous test
    255      istream = imgTools.encodeImage(container, "image/png");
    256      encodedBytes = streamToArray(istream);
    257 
    258      // Get bytes for expected result
    259      if (AppConstants.USE_LIBZ_RS) {
    260        refName = "image2jpg32x32.libz-rs.png";
    261      } else {
    262        refName = isWindows ? "image2jpg32x32-win.png" : "image2jpg32x32.png";
    263      }
    264      refFile = do_get_file(refName);
    265      istream = getFileInputStream(refFile);
    266      Assert.equal(istream.available(), AppConstants.USE_LIBZ_RS ? 2916 : 3026);
    267      referenceBytes = streamToArray(istream);
    268 
    269      // compare the encoder's output to the reference file.
    270      compareArrays(encodedBytes, referenceBytes);
    271    }
    272 
    273    /* ========== 7 ========== */
    274    testnum++;
    275    testdesc = "test decoding a ICO";
    276 
    277    // 16x16 ico, 1406 bytes.
    278    imgName = "image3.ico";
    279    inMimeType = "image/x-icon";
    280    imgFile = do_get_file(imgName);
    281 
    282    istream = getFileInputStream(imgFile);
    283    Assert.equal(istream.available(), 1406);
    284 
    285    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    286    container = imgTools.decodeImageFromBuffer(
    287      buffer,
    288      buffer.length,
    289      inMimeType
    290    );
    291 
    292    // It's not easy to look at the pixel values from JS, so just
    293    // check the container's size.
    294    Assert.equal(container.width, 16);
    295    Assert.equal(container.height, 16);
    296 
    297    /* ========== 8 ========== */
    298    testnum++;
    299    testdesc = "test encoding a scaled PNG"; // note that we're scaling UP
    300 
    301    // we'll reuse the container from the previous test
    302    istream = imgTools.encodeScaledImage(container, "image/png", 32, 32);
    303    encodedBytes = streamToArray(istream);
    304 
    305    // Get bytes for expected result
    306    refName = AppConstants.USE_LIBZ_RS
    307      ? "image3ico32x32.libz-rs.png"
    308      : "image3ico32x32.png";
    309    refFile = do_get_file(refName);
    310    istream = getFileInputStream(refFile);
    311    Assert.equal(istream.available(), AppConstants.USE_LIBZ_RS ? 2285 : 2280);
    312    referenceBytes = streamToArray(istream);
    313 
    314    // compare the encoder's output to the reference file.
    315    compareArrays(encodedBytes, referenceBytes);
    316 
    317    /* ========== 9 ========== */
    318    testnum++;
    319    testdesc = "test encoding an unscaled PNG";
    320 
    321    // we'll reuse the container from the previous test
    322    istream = imgTools.encodeImage(container, "image/png");
    323    encodedBytes = streamToArray(istream);
    324 
    325    // Get bytes for expected result
    326    refName = AppConstants.USE_LIBZ_RS
    327      ? "image3ico16x16.libz-rs.png"
    328      : "image3ico16x16.png";
    329    refFile = do_get_file(refName);
    330    istream = getFileInputStream(refFile);
    331    Assert.equal(istream.available(), AppConstants.USE_LIBZ_RS ? 512 : 520);
    332    referenceBytes = streamToArray(istream);
    333 
    334    // compare the encoder's output to the reference file.
    335    compareArrays(encodedBytes, referenceBytes);
    336 
    337    /* ========== 10 ========== */
    338    testnum++;
    339    testdesc = "test decoding a GIF";
    340 
    341    // 32x32 gif, 1809 bytes.
    342    imgName = "image4.gif";
    343    inMimeType = "image/gif";
    344    imgFile = do_get_file(imgName);
    345 
    346    istream = getFileInputStream(imgFile);
    347    Assert.equal(istream.available(), 1809);
    348 
    349    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    350    container = imgTools.decodeImageFromBuffer(
    351      buffer,
    352      buffer.length,
    353      inMimeType
    354    );
    355 
    356    // It's not easy to look at the pixel values from JS, so just
    357    // check the container's size.
    358    Assert.equal(container.width, 32);
    359    Assert.equal(container.height, 32);
    360 
    361    /* ========== 11 ========== */
    362    testnum++;
    363    testdesc =
    364      "test encoding an unscaled ICO with format options " +
    365      "(format=bmp;bpp=32)";
    366 
    367    // we'll reuse the container from the previous test
    368    istream = imgTools.encodeImage(
    369      container,
    370      "image/vnd.microsoft.icon",
    371      "format=bmp;bpp=32"
    372    );
    373    encodedBytes = streamToArray(istream);
    374 
    375    // Get bytes for expected result
    376    refName = "image4gif32x32bmp32bpp.ico";
    377    refFile = do_get_file(refName);
    378    istream = getFileInputStream(refFile);
    379    Assert.equal(istream.available(), 4286);
    380    referenceBytes = streamToArray(istream);
    381 
    382    // compare the encoder's output to the reference file.
    383    compareArrays(encodedBytes, referenceBytes);
    384 
    385    /* ========== 12 ========== */
    386    testnum++;
    387    testdesc =
    388      // eslint-disable-next-line no-useless-concat
    389      "test encoding a scaled ICO with format options " + "(format=bmp;bpp=32)";
    390 
    391    // we'll reuse the container from the previous test
    392    istream = imgTools.encodeScaledImage(
    393      container,
    394      "image/vnd.microsoft.icon",
    395      16,
    396      16,
    397      "format=bmp;bpp=32"
    398    );
    399    encodedBytes = streamToArray(istream);
    400 
    401    // Get bytes for expected result
    402    refName = "image4gif16x16bmp32bpp.ico";
    403    refFile = do_get_file(refName);
    404    istream = getFileInputStream(refFile);
    405    Assert.equal(istream.available(), 1150);
    406    referenceBytes = streamToArray(istream);
    407 
    408    // compare the encoder's output to the reference file.
    409    compareArrays(encodedBytes, referenceBytes);
    410 
    411    /* ========== 13 ========== */
    412    testnum++;
    413    testdesc =
    414      "test encoding an unscaled ICO with format options " +
    415      "(format=bmp;bpp=24)";
    416 
    417    // we'll reuse the container from the previous test
    418    istream = imgTools.encodeImage(
    419      container,
    420      "image/vnd.microsoft.icon",
    421      "format=bmp;bpp=24"
    422    );
    423    encodedBytes = streamToArray(istream);
    424 
    425    // Get bytes for expected result
    426    refName = "image4gif32x32bmp24bpp.ico";
    427    refFile = do_get_file(refName);
    428    istream = getFileInputStream(refFile);
    429    Assert.equal(istream.available(), 3262);
    430    referenceBytes = streamToArray(istream);
    431 
    432    // compare the encoder's output to the reference file.
    433    compareArrays(encodedBytes, referenceBytes);
    434 
    435    /* ========== 14 ========== */
    436    testnum++;
    437    testdesc =
    438      // eslint-disable-next-line no-useless-concat
    439      "test encoding a scaled ICO with format options " + "(format=bmp;bpp=24)";
    440 
    441    // we'll reuse the container from the previous test
    442    istream = imgTools.encodeScaledImage(
    443      container,
    444      "image/vnd.microsoft.icon",
    445      16,
    446      16,
    447      "format=bmp;bpp=24"
    448    );
    449    encodedBytes = streamToArray(istream);
    450 
    451    // Get bytes for expected result
    452    refName = "image4gif16x16bmp24bpp.ico";
    453    refFile = do_get_file(refName);
    454    istream = getFileInputStream(refFile);
    455    Assert.equal(istream.available(), 894);
    456    referenceBytes = streamToArray(istream);
    457 
    458    // compare the encoder's output to the reference file.
    459    compareArrays(encodedBytes, referenceBytes);
    460 
    461    /* ========== 15 ========== */
    462    testnum++;
    463    testdesc = "test cropping a JPG";
    464 
    465    // 32x32 jpeg, 3494 bytes.
    466    imgName = "image2.jpg";
    467    inMimeType = "image/jpeg";
    468    imgFile = do_get_file(imgName);
    469 
    470    istream = getFileInputStream(imgFile);
    471    Assert.equal(istream.available(), 3494);
    472 
    473    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    474    container = imgTools.decodeImageFromBuffer(
    475      buffer,
    476      buffer.length,
    477      inMimeType
    478    );
    479 
    480    // It's not easy to look at the pixel values from JS, so just
    481    // check the container's size.
    482    Assert.equal(container.width, 32);
    483    Assert.equal(container.height, 32);
    484 
    485    // encode a cropped image
    486    istream = imgTools.encodeCroppedImage(
    487      container,
    488      "image/jpeg",
    489      0,
    490      0,
    491      16,
    492      16
    493    );
    494    encodedBytes = streamToArray(istream);
    495 
    496    // Get bytes for expected result
    497    refName = "image2jpg16x16cropped.jpg";
    498    refFile = do_get_file(refName);
    499    istream = getFileInputStream(refFile);
    500    Assert.equal(istream.available(), 879);
    501    referenceBytes = streamToArray(istream);
    502 
    503    // compare the encoder's output to the reference file.
    504    compareArrays(encodedBytes, referenceBytes);
    505 
    506    /* ========== 16 ========== */
    507    testnum++;
    508    testdesc = "test cropping a JPG with an offset";
    509 
    510    // we'll reuse the container from the previous test
    511    istream = imgTools.encodeCroppedImage(
    512      container,
    513      "image/jpeg",
    514      16,
    515      16,
    516      16,
    517      16
    518    );
    519    encodedBytes = streamToArray(istream);
    520 
    521    // Get bytes for expected result
    522    refName = "image2jpg16x16cropped2.jpg";
    523    refFile = do_get_file(refName);
    524    istream = getFileInputStream(refFile);
    525    Assert.equal(istream.available(), 878);
    526    referenceBytes = streamToArray(istream);
    527 
    528    // compare the encoder's output to the reference file.
    529    compareArrays(encodedBytes, referenceBytes);
    530 
    531    /* ========== 17 ========== */
    532    testnum++;
    533    testdesc = "test cropping a JPG without a given height";
    534 
    535    // we'll reuse the container from the previous test
    536    istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 16, 0);
    537    encodedBytes = streamToArray(istream);
    538 
    539    // Get bytes for expected result
    540    refName = "image2jpg16x32cropped3.jpg";
    541    refFile = do_get_file(refName);
    542    istream = getFileInputStream(refFile);
    543    Assert.equal(istream.available(), 1127);
    544    referenceBytes = streamToArray(istream);
    545 
    546    // compare the encoder's output to the reference file.
    547    compareArrays(encodedBytes, referenceBytes);
    548 
    549    /* ========== 18 ========== */
    550    testnum++;
    551    testdesc = "test cropping a JPG without a given width";
    552 
    553    // we'll reuse the container from the previous test
    554    istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 16);
    555    encodedBytes = streamToArray(istream);
    556 
    557    // Get bytes for expected result
    558    refName = "image2jpg32x16cropped4.jpg";
    559    refFile = do_get_file(refName);
    560    istream = getFileInputStream(refFile);
    561    Assert.equal(istream.available(), 1135);
    562    referenceBytes = streamToArray(istream);
    563 
    564    // compare the encoder's output to the reference file.
    565    compareArrays(encodedBytes, referenceBytes);
    566 
    567    /* ========== 19 ========== */
    568    testnum++;
    569    testdesc = "test cropping a JPG without a given width and height";
    570 
    571    // we'll reuse the container from the previous test
    572    istream = imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 0, 0);
    573    encodedBytes = streamToArray(istream);
    574 
    575    // Get bytes for expected result
    576    refName = "image2jpg32x32.jpg";
    577    refFile = do_get_file(refName);
    578    istream = getFileInputStream(refFile);
    579    Assert.equal(istream.available(), 1634);
    580    referenceBytes = streamToArray(istream);
    581 
    582    // compare the encoder's output to the reference file.
    583    compareArrays(encodedBytes, referenceBytes);
    584 
    585    /* ========== 20 ========== */
    586    testnum++;
    587    testdesc = "test scaling a JPG without a given width";
    588 
    589    // we'll reuse the container from the previous test
    590    istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 16);
    591    encodedBytes = streamToArray(istream);
    592 
    593    // Get bytes for expected result
    594    refName = "image2jpg32x16scaled.jpg";
    595    refFile = do_get_file(refName);
    596    istream = getFileInputStream(refFile);
    597    Assert.equal(istream.available(), 1227);
    598    referenceBytes = streamToArray(istream);
    599 
    600    // compare the encoder's output to the reference file.
    601    compareArrays(encodedBytes, referenceBytes);
    602 
    603    /* ========== 21 ========== */
    604    testnum++;
    605    testdesc = "test scaling a JPG without a given height";
    606 
    607    // we'll reuse the container from the previous test
    608    istream = imgTools.encodeScaledImage(container, "image/jpeg", 16, 0);
    609    encodedBytes = streamToArray(istream);
    610 
    611    // Get bytes for expected result
    612    refName = "image2jpg16x32scaled.jpg";
    613    refFile = do_get_file(refName);
    614    istream = getFileInputStream(refFile);
    615    Assert.equal(istream.available(), 1219);
    616    referenceBytes = streamToArray(istream);
    617 
    618    // compare the encoder's output to the reference file.
    619    compareArrays(encodedBytes, referenceBytes);
    620 
    621    /* ========== 22 ========== */
    622    testnum++;
    623    testdesc = "test scaling a JPG without a given width and height";
    624 
    625    // we'll reuse the container from the previous test
    626    istream = imgTools.encodeScaledImage(container, "image/jpeg", 0, 0);
    627    encodedBytes = streamToArray(istream);
    628 
    629    // Get bytes for expected result
    630    refName = "image2jpg32x32.jpg";
    631    refFile = do_get_file(refName);
    632    istream = getFileInputStream(refFile);
    633    Assert.equal(istream.available(), 1634);
    634    referenceBytes = streamToArray(istream);
    635 
    636    // compare the encoder's output to the reference file.
    637    compareArrays(encodedBytes, referenceBytes);
    638 
    639    /* ========== 23 ========== */
    640    testnum++;
    641    testdesc = "test invalid arguments for cropping";
    642 
    643    var numErrors = 0;
    644 
    645    try {
    646      // width/height can't be negative
    647      imgTools.encodeScaledImage(container, "image/jpeg", -1, -1);
    648    } catch (e) {
    649      numErrors++;
    650    }
    651 
    652    try {
    653      // offsets can't be negative
    654      imgTools.encodeCroppedImage(container, "image/jpeg", -1, -1, 16, 16);
    655    } catch (e) {
    656      numErrors++;
    657    }
    658 
    659    try {
    660      // width/height can't be negative
    661      imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, -1, -1);
    662    } catch (e) {
    663      numErrors++;
    664    }
    665 
    666    try {
    667      // out of bounds
    668      imgTools.encodeCroppedImage(container, "image/jpeg", 17, 17, 16, 16);
    669    } catch (e) {
    670      numErrors++;
    671    }
    672 
    673    try {
    674      // out of bounds
    675      imgTools.encodeCroppedImage(container, "image/jpeg", 0, 0, 33, 33);
    676    } catch (e) {
    677      numErrors++;
    678    }
    679 
    680    try {
    681      // out of bounds
    682      imgTools.encodeCroppedImage(container, "image/jpeg", 1, 1, 0, 0);
    683    } catch (e) {
    684      numErrors++;
    685    }
    686 
    687    Assert.equal(numErrors, 6);
    688 
    689    /* ========== 24 ========== */
    690    testnum++;
    691    testdesc = "test encoding webp";
    692 
    693    // Load picture that we want to convert
    694    imgName = "image1.png";
    695    inMimeType = "image/png";
    696    imgFile = do_get_file(imgName);
    697 
    698    istream = getFileInputStream(imgFile);
    699    Assert.equal(istream.available(), 8415);
    700 
    701    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    702    container = imgTools.decodeImageFromBuffer(
    703      buffer,
    704      buffer.length,
    705      inMimeType
    706    );
    707 
    708    // Convert image to webp
    709    istream = imgTools.encodeImage(container, "image/webp");
    710    encodedBytes = streamToArray(istream);
    711 
    712    // Get bytes for expected result
    713    refName = "image1.webp";
    714    refFile = do_get_file(refName);
    715    istream = getFileInputStream(refFile);
    716    Assert.equal(istream.available(), 3206);
    717    referenceBytes = streamToArray(istream);
    718 
    719    // compare the encoder's output to the reference file.
    720    compareArrays(encodedBytes, referenceBytes);
    721 
    722    /* ========== 25 ========== */
    723    testnum++;
    724    testdesc = "test encoding webp with quality parameter";
    725 
    726    // Load picture that we want to convert
    727    imgName = "image1.png";
    728    inMimeType = "image/png";
    729    imgFile = do_get_file(imgName);
    730 
    731    istream = getFileInputStream(imgFile);
    732    Assert.equal(istream.available(), 8415);
    733 
    734    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    735    container = imgTools.decodeImageFromBuffer(
    736      buffer,
    737      buffer.length,
    738      inMimeType
    739    );
    740 
    741    // Convert image to webp
    742    istream = imgTools.encodeImage(container, "image/webp", "quality=50");
    743    encodedBytes = streamToArray(istream);
    744 
    745    // Get bytes for expected result
    746    refName = "image1quality50.webp";
    747    refFile = do_get_file(refName);
    748    istream = getFileInputStream(refFile);
    749    Assert.equal(istream.available(), 1944);
    750    referenceBytes = streamToArray(istream);
    751 
    752    // compare the encoder's output to the reference file.
    753    compareArrays(encodedBytes, referenceBytes);
    754 
    755    /* ========== bug 363986 ========== */
    756    testnum = 363986;
    757    testdesc = "test PNG and JPEG and WEBP encoders' Read/ReadSegments methods";
    758 
    759    var testData = [
    760      {
    761        preImage: "image3.ico",
    762        preImageMimeType: "image/x-icon",
    763        refImage: AppConstants.USE_LIBZ_RS
    764          ? "image3ico16x16.libz-rs.png"
    765          : "image3ico16x16.png",
    766        refImageMimeType: "image/png",
    767      },
    768      {
    769        preImage: "image1.png",
    770        preImageMimeType: "image/png",
    771        refImage: "image1png64x64.jpg",
    772        refImageMimeType: "image/jpeg",
    773      },
    774      {
    775        preImage: "image1.png",
    776        preImageMimeType: "image/png",
    777        refImage: "image1.webp",
    778        refImageMimeType: "image/webp",
    779      },
    780    ];
    781 
    782    for (var i = 0; i < testData.length; ++i) {
    783      var dict = testData[i];
    784 
    785      imgFile = do_get_file(dict.refImage);
    786      istream = getFileInputStream(imgFile);
    787      var refBytes = streamToArray(istream);
    788 
    789      imgFile = do_get_file(dict.preImage);
    790      istream = getFileInputStream(imgFile);
    791 
    792      buffer = NetUtil.readInputStreamToString(istream, istream.available());
    793      container = imgTools.decodeImageFromBuffer(
    794        buffer,
    795        buffer.length,
    796        dict.preImageMimeType
    797      );
    798 
    799      istream = imgTools.encodeImage(container, dict.refImageMimeType);
    800 
    801      var sstream = Cc["@mozilla.org/storagestream;1"].createInstance(
    802        Ci.nsIStorageStream
    803      );
    804      sstream.init(4096, 4294967295, null);
    805      var ostream = sstream.getOutputStream(0);
    806      var bostream = Cc[
    807        "@mozilla.org/network/buffered-output-stream;1"
    808      ].createInstance(Ci.nsIBufferedOutputStream);
    809 
    810      // use a tiny buffer to make sure the image data doesn't fully fit in it
    811      bostream.init(ostream, 8);
    812 
    813      bostream.writeFrom(istream, istream.available());
    814      bostream.flush();
    815      bostream.close();
    816 
    817      var encBytes = streamToArray(sstream.newInputStream(0));
    818 
    819      compareArrays(refBytes, encBytes);
    820    }
    821 
    822    /* ========== bug 413512  ========== */
    823    testnum = 413512;
    824    testdesc = "test decoding bad favicon (bug 413512)";
    825 
    826    imgName = "bug413512.ico";
    827    inMimeType = "image/x-icon";
    828    imgFile = do_get_file(imgName);
    829 
    830    istream = getFileInputStream(imgFile);
    831    Assert.equal(istream.available(), 17759);
    832    var errsrc = "none";
    833 
    834    try {
    835      buffer = NetUtil.readInputStreamToString(istream, istream.available());
    836      container = imgTools.decodeImageFromBuffer(
    837        buffer,
    838        buffer.length,
    839        inMimeType
    840      );
    841 
    842      // We expect to hit an error during encoding because the ICO header of the
    843      // image is fine, but the actual resources are corrupt. Since
    844      // decodeImageFromBuffer() only performs a metadata decode, it doesn't decode
    845      // far enough to realize this, but we'll find out when we do a full decode
    846      // during encodeImage().
    847      try {
    848        istream = imgTools.encodeImage(container, "image/png");
    849      } catch (e) {
    850        err = e;
    851        errsrc = "encode";
    852      }
    853    } catch (e) {
    854      err = e;
    855      errsrc = "decode";
    856    }
    857 
    858    Assert.equal(errsrc, "encode");
    859    checkExpectedError(/NS_ERROR_FAILURE/, err);
    860 
    861    /* ========== bug 815359  ========== */
    862    testnum = 815359;
    863    testdesc = "test correct ico hotspots (bug 815359)";
    864 
    865    imgName = "bug815359.ico";
    866    inMimeType = "image/x-icon";
    867    imgFile = do_get_file(imgName);
    868 
    869    istream = getFileInputStream(imgFile);
    870    Assert.equal(istream.available(), 4286);
    871 
    872    buffer = NetUtil.readInputStreamToString(istream, istream.available());
    873    container = imgTools.decodeImageFromBuffer(
    874      buffer,
    875      buffer.length,
    876      inMimeType
    877    );
    878 
    879    Assert.equal(container.hotspotX, 10);
    880    Assert.equal(container.hotspotY, 9);
    881 
    882    /* ========== end ========== */
    883  } catch (e) {
    884    throw new Error(
    885      "FAILED in test #" + testnum + " -- " + testdesc + ": " + e
    886    );
    887  }
    888 }