buildDecTable static method

void buildDecTable(
  1. List<int> hcode,
  2. int im,
  3. int iM,
  4. List<ExrHufDec> hdecod,
)

Implementation

static void buildDecTable(
    List<int> hcode, int im, int iM, List<ExrHufDec> hdecod) {
  // Init hashtable & loop on all codes.
  // Assumes that hufClearDecTable(hdecod) has already been called.
  for (; im <= iM; im++) {
    final c = hufCode(hcode[im]);
    final l = hufLength(hcode[im]);

    if (c >> l != 0) {
      // Error: c is supposed to be an l-bit code,
      // but c contains a value that is greater
      // than the largest l-bit number.
      throw ImageException('Error in Huffman-encoded data '
          '(invalid code table entry).');
    }

    if (l > HUF_DECBITS) {
      // Long code: add a secondary entry
      final pl = hdecod[(c >> (l - HUF_DECBITS))];

      if (pl.len != 0) {
        // Error: a short code has already
        // been stored in table entry *pl.
        throw ImageException('Error in Huffman-encoded data '
            '(invalid code table entry).');
      }

      pl.lit++;

      if (pl.p != null) {
        final p = pl.p;
        pl.p = List<int>.filled(pl.lit, 0);

        for (var i = 0; i < pl.lit - 1; ++i) {
          pl.p![i] = p![i];
        }
      } else {
        pl.p = [0];
      }

      pl.p![pl.lit - 1] = im;
    } else if (l != 0) {
      // Short code: init all primary entries
      var pi = (c << (HUF_DECBITS - l));
      var pl = hdecod[pi];

      for (var i = 1 << (HUF_DECBITS - l); i > 0; i--, pi++) {
        pl = hdecod[pi];
        if (pl.len != 0 || pl.p != null) {
          // Error: a short code or a long code has
          // already been stored in table entry *pl.
          throw ImageException('Error in Huffman-encoded data '
              '(invalid code table entry).');
        }

        pl.len = l;
        pl.lit = im;
      }
    }
  }
}