// File: tomfunkhouser[P]gaps/pkgs/jpeg/jdhuff.c
// Function: jpeg_make_d_derived_tbl
GLOBAL(void)
jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, jboolean isDC, int tblno,
			 d_derived_tbl ** pdtbl)
{
  JHUFF_TBL *htbl;
  d_derived_tbl *dtbl;
  int p, i, l, si, numsymbols;
  int lookbits, ctr;
  char huffsize[257];
  unsigned int huffcode[257];
  unsigned int code;

  /* Note that huffsize[] and huffcode[] are filled in code-length order,
   * paralleling the order of the symbols themselves in htbl->huffval[].
   */

  /* Find the input Huffman table */
  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
  htbl =
    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
  if (htbl == NULL)
    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);

  /* Allocate a workspace if we haven't already done so. */
  if (*pdtbl == NULL)
    *pdtbl = (d_derived_tbl *)
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				  SIZEOF(d_derived_tbl));
  dtbl = *pdtbl;
  dtbl->pub = htbl;		/* fill in back link */
  
  /* Figure C.1: make table of Huffman code length for each symbol */

  p = 0;
  for (l = 1; l <= 16; l++) {
    i = (int) htbl->bits[l];
    if (i < 0 || p + i > 256)	/* protect against table overrun */
      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    while (i--)
      huffsize[p++] = (char) l;
  }
  huffsize[p] = 0;
  numsymbols = p;
  
  /* Figure C.2: generate the codes themselves */
  /* We also validate that the counts represent a legal Huffman code tree. */
  
  code = 0;
  si = huffsize[0];
  p = 0;
  while (huffsize[p]) {
    while (((int) huffsize[p]) == si) {
      huffcode[p++] = code;
      code++;
    }
    /* code is now 1 more than the last code used for codelength si; but
     * it must still fit in si bits, since no code is allowed to be all ones.
     */
    if (((INT32) code) >= (((INT32) 1) << si))
      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    code <<= 1;
    si++;
  }

  /* Figure F.15: generate decoding tables for bit-sequential decoding */

  p = 0;
  for (l = 1; l <= 16; l++) {
    if (htbl->bits[l]) {
      /* valoffset[l] = huffval[] index of 1st symbol of code length l,
       * minus the minimum code of length l
       */
      dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
      p += htbl->bits[l];
      dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
    } else {
      dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */
    }
  }
  dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */

  /* Compute lookahead tables to speed up decoding.
   * First we set all the table entries to 0, indicating "too long";
   * then we iterate through the Huffman codes that are short enough and
   * fill in all the entries that correspond to bit sequences starting
   * with that code.
   */

  MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));

  p = 0;
  for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
    for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
      /* l = current code's length, p = its index in huffcode[] & huffval[]. */
      /* Generate left-justified code followed by all possible bit sequences */
      lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
      for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
	dtbl->look_nbits[lookbits] = l;
	dtbl->look_sym[lookbits] = htbl->huffval[p];
	lookbits++;
      }
    }
  }

  /* Validate symbols as being reasonable.
   * For AC tables, we make no check, but accept all byte values 0..255.
   * For DC tables, we require the symbols to be in range 0..15.
   * (Tighter bounds could be applied depending on the data depth and mode,
   * but this is sufficient to ensure safe decoding.)
   */
  if (isDC) {
    for (i = 0; i < numsymbols; i++) {
      int sym = htbl->huffval[i];
      if (sym < 0 || sym > 15)
	ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    }
  }
}

// Assembly:
subq $0x568, %rsp            # imm = 0x568
movq %rdi, 0x560(%rsp)
movl %esi, 0x55c(%rsp)
movl %edx, 0x558(%rsp)
movq %rcx, 0x550(%rsp)
cmpl $0x0, 0x558(%rsp)
jl 0xe91c9
cmpl $0x4, 0x558(%rsp)
jl 0xe9208
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl $0x32, 0x28(%rax)
movl 0x558(%rsp), %ecx
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x2c(%rax)
movq 0x560(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x560(%rsp), %rdi
callq *%rax
cmpl $0x0, 0x55c(%rsp)
je 0xe9230
movq 0x560(%rsp), %rax
movslq 0x558(%rsp), %rcx
movq 0xe8(%rax,%rcx,8), %rax
movq %rax, (%rsp)
jmp 0xe924c
movq 0x560(%rsp), %rax
movslq 0x558(%rsp), %rcx
movq 0x108(%rax,%rcx,8), %rax
movq %rax, (%rsp)
movq (%rsp), %rax
movq %rax, 0x548(%rsp)
cmpq $0x0, 0x548(%rsp)
jne 0xe92a2
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl $0x32, 0x28(%rax)
movl 0x558(%rsp), %ecx
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x2c(%rax)
movq 0x560(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x560(%rsp), %rdi
callq *%rax
movq 0x550(%rsp), %rax
cmpq $0x0, (%rax)
jne 0xe92e1
movq 0x560(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq 0x560(%rsp), %rdi
movl $0x1, %esi
movl $0x620, %edx            # imm = 0x620
callq *%rax
movq %rax, %rcx
movq 0x550(%rsp), %rax
movq %rcx, (%rax)
movq 0x550(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x540(%rsp)
movq 0x548(%rsp), %rcx
movq 0x540(%rsp), %rax
movq %rcx, 0x118(%rax)
movl $0x0, 0x53c(%rsp)
movl $0x1, 0x534(%rsp)
cmpl $0x10, 0x534(%rsp)
jg 0xe93ec
movq 0x548(%rsp), %rax
movslq 0x534(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, 0x538(%rsp)
cmpl $0x0, 0x538(%rsp)
jl 0xe9369
movl 0x53c(%rsp), %eax
addl 0x538(%rsp), %eax
cmpl $0x100, %eax            # imm = 0x100
jle 0xe9393
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl $0x8, 0x28(%rax)
movq 0x560(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x560(%rsp), %rdi
callq *%rax
jmp 0xe9395
movl 0x538(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, 0x538(%rsp)
cmpl $0x0, %eax
je 0xe93d4
movl 0x534(%rsp), %eax
movb %al, %cl
movl 0x53c(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x53c(%rsp)
cltq
movb %cl, 0x420(%rsp,%rax)
jmp 0xe9395
jmp 0xe93d6
movl 0x534(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x534(%rsp)
jmp 0xe9321
movslq 0x53c(%rsp), %rax
movb $0x0, 0x420(%rsp,%rax)
movl 0x53c(%rsp), %eax
movl %eax, 0x52c(%rsp)
movl $0x0, 0xc(%rsp)
movsbl 0x420(%rsp), %eax
movl %eax, 0x530(%rsp)
movl $0x0, 0x53c(%rsp)
movslq 0x53c(%rsp), %rax
cmpb $0x0, 0x420(%rsp,%rax)
je 0xe94ec
jmp 0xe9444
movslq 0x53c(%rsp), %rax
movsbl 0x420(%rsp,%rax), %eax
cmpl 0x530(%rsp), %eax
jne 0xe9487
movl 0xc(%rsp), %ecx
movl 0x53c(%rsp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x53c(%rsp)
cltq
movl %ecx, 0x10(%rsp,%rax,4)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0xe9444
movl 0xc(%rsp), %eax
movl 0x530(%rsp), %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
cmpq %rcx, %rax
jl 0xe94cc
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl $0x8, 0x28(%rax)
movq 0x560(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x560(%rsp), %rdi
callq *%rax
movl 0xc(%rsp), %eax
shll %eax
movl %eax, 0xc(%rsp)
movl 0x530(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x530(%rsp)
jmp 0xe942c
movl $0x0, 0x53c(%rsp)
movl $0x1, 0x534(%rsp)
cmpl $0x10, 0x534(%rsp)
jg 0xe95cf
movq 0x548(%rsp), %rax
movslq 0x534(%rsp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0xe959f
movslq 0x53c(%rsp), %rdx
movslq 0x53c(%rsp), %rax
movl 0x10(%rsp,%rax,4), %eax
subq %rax, %rdx
movq 0x540(%rsp), %rax
movslq 0x534(%rsp), %rcx
movq %rdx, 0x90(%rax,%rcx,8)
movq 0x548(%rsp), %rax
movslq 0x534(%rsp), %rcx
movzbl (%rax,%rcx), %eax
addl 0x53c(%rsp), %eax
movl %eax, 0x53c(%rsp)
movl 0x53c(%rsp), %eax
subl $0x1, %eax
cltq
movl 0x10(%rsp,%rax,4), %eax
movl %eax, %edx
movq 0x540(%rsp), %rax
movslq 0x534(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0xe95b7
movq 0x540(%rsp), %rax
movslq 0x534(%rsp), %rcx
movq $-0x1, (%rax,%rcx,8)
jmp 0xe95b9
movl 0x534(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x534(%rsp)
jmp 0xe9502
movq 0x540(%rsp), %rax
movq $0xfffff, 0x88(%rax) # imm = 0xFFFFF
movq 0x540(%rsp), %rdi
addq $0x120, %rdi            # imm = 0x120
xorl %esi, %esi
movl $0x400, %edx            # imm = 0x400
callq 0xf280
movl $0x0, 0x53c(%rsp)
movl $0x1, 0x534(%rsp)
cmpl $0x8, 0x534(%rsp)
jg 0xe9742
movl $0x1, 0x538(%rsp)
movl 0x538(%rsp), %eax
movq 0x548(%rsp), %rcx
movslq 0x534(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jg 0xe972a
movslq 0x53c(%rsp), %rax
movl 0x10(%rsp,%rax,4), %eax
movl $0x8, %ecx
subl 0x534(%rsp), %ecx
shll %cl, %eax
movl %eax, 0x528(%rsp)
movl $0x8, %ecx
subl 0x534(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, 0x524(%rsp)
cmpl $0x0, 0x524(%rsp)
jle 0xe9701
movl 0x534(%rsp), %edx
movq 0x540(%rsp), %rax
movslq 0x528(%rsp), %rcx
movl %edx, 0x120(%rax,%rcx,4)
movq 0x548(%rsp), %rax
movslq 0x53c(%rsp), %rcx
movb 0x11(%rax,%rcx), %dl
movq 0x540(%rsp), %rax
movslq 0x528(%rsp), %rcx
movb %dl, 0x520(%rax,%rcx)
movl 0x528(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x528(%rsp)
movl 0x524(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x524(%rsp)
jmp 0xe968a
jmp 0xe9703
movl 0x538(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x538(%rsp)
movl 0x53c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x53c(%rsp)
jmp 0xe962c
jmp 0xe972c
movl 0x534(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x534(%rsp)
jmp 0xe9613
cmpl $0x0, 0x55c(%rsp)
je 0xe97d3
movl $0x0, 0x538(%rsp)
movl 0x538(%rsp), %eax
cmpl 0x52c(%rsp), %eax
jge 0xe97d1
movq 0x548(%rsp), %rax
movslq 0x538(%rsp), %rcx
movzbl 0x11(%rax,%rcx), %eax
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jl 0xe9792
cmpl $0xf, 0x8(%rsp)
jle 0xe97bc
movq 0x560(%rsp), %rax
movq (%rax), %rax
movl $0x8, 0x28(%rax)
movq 0x560(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x560(%rsp), %rdi
callq *%rax
jmp 0xe97be
movl 0x538(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x538(%rsp)
jmp 0xe975b
jmp 0xe97d3
addq $0x568, %rsp            # imm = 0x568
retq
nopl (%rax,%rax)