function buildHuffmanTable(codeLengths, values) {
  let k = 0,
    i,
    j,
    length = 16;
  while (length > 0 && !codeLengths[length - 1]) {
    length--;
  }
  const code = [{ children: [], index: 0 }];
  let p = code[0],
    q;
  for (i = 0; i < length; i++) {
    for (j = 0; j < codeLengths[i]; j++) {
      p = code.pop();
      p.children[p.index] = values[k];
      while (p.index > 0) {
        p = code.pop();
      }
      p.index++;
      code.push(p);
      while (code.length <= i) {
        code.push((q = { children: [], index: 0 }));
        p.children[p.index] = q.children;
        p = q;
      }
      k++;
    }
    if (i + 1 < length) {
      // p here points to last code
      code.push((q = { children: [], index: 0 }));
      p.children[p.index] = q.children;
      p = q;
    }
  }
  return code[0].children;
}
This code was forked from https://github.com/notmasteryet/jpgjs.
The original version was created by GitHub user notmasteryet.

- The JPEG specification can be found in the ITU CCITT Recommendation T.81
  (www.w3.org/Graphics/JPEG/itu-t81.pdf)
- The JFIF specification can be found in the JPEG File Interchange Format
  (www.w3.org/Graphics/JPEG/jfif3.pdf)
- The Adobe Application-Specific JPEG markers in the
  Supporting the DCT Filters in PostScript Level 2, Technical Note #5116
  (partners.adobe.com/public/developer/en/ps/sdk/5116.DCT_Filter.pdf)