// File: /workspace/github_c_makefile_star2_O0/pje[P]pixelsort/lodepng.c
// Function: lodepng_huffman_code_lengths
unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies,
                                      size_t numcodes, unsigned maxbitlen)
{
  unsigned i, j;
  size_t sum = 0, numpresent = 0;
  unsigned error = 0;
  Coin* coins; /*the coins of the currently calculated row*/
  Coin* prev_row; /*the previous row of coins*/
  size_t numcoins;
  size_t coinmem;

  if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/

  for(i = 0; i < numcodes; i++)
  {
    if(frequencies[i] > 0)
    {
      numpresent++;
      sum += frequencies[i];
    }
  }

  for(i = 0; i < numcodes; i++) lengths[i] = 0;

  /*ensure at least two present symbols. There should be at least one symbol
  according to RFC 1951 section 3.2.7. To decoders incorrectly require two. To
  make these work as well ensure there are at least two symbols. The
  Package-Merge code below also doesn't work correctly if there's only one
  symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/
  if(numpresent == 0)
  {
    lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/
  }
  else if(numpresent == 1)
  {
    for(i = 0; i < numcodes; i++)
    {
      if(frequencies[i])
      {
        lengths[i] = 1;
        lengths[i == 0 ? 1 : 0] = 1;
        break;
      }
    }
  }
  else
  {
    /*Package-Merge algorithm represented by coin collector's problem
    For every symbol, maxbitlen coins will be created*/

    coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/
    coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem);
    prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem);
    if(!coins || !prev_row)
    {
      lodepng_free(coins);
      lodepng_free(prev_row);
      return 83; /*alloc fail*/
    }
    init_coins(coins, coinmem);
    init_coins(prev_row, coinmem);

    /*first row, lowest denominator*/
    error = append_symbol_coins(coins, frequencies, numcodes, sum);
    numcoins = numpresent;
    qsort(coins, numcoins, sizeof(Coin), coin_compare);
    if(!error)
    {
      unsigned numprev = 0;
      for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/
      {
        unsigned tempnum;
        Coin* tempcoins;
        /*swap prev_row and coins, and their amounts*/
        tempcoins = prev_row; prev_row = coins; coins = tempcoins;
        tempnum = numprev; numprev = numcoins; numcoins = tempnum;

        cleanup_coins(coins, numcoins);
        init_coins(coins, numcoins);

        numcoins = 0;

        /*fill in the merged coins of the previous row*/
        for(i = 0; i + 1 < numprev; i += 2)
        {
          /*merge prev_row[i] and prev_row[i + 1] into new coin*/
          Coin* coin = &coins[numcoins++];
          coin_copy(coin, &prev_row[i]);
          add_coins(coin, &prev_row[i + 1]);
        }
        /*fill in all the original symbols again*/
        if(j < maxbitlen)
        {
          error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum);
          numcoins += numpresent;
        }
        qsort(coins, numcoins, sizeof(Coin), coin_compare);
      }
    }

    if(!error)
    {
      /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/
      for(i = 0; i < numpresent - 1; i++)
      {
        Coin* coin = &coins[i];
        for(j = 0; j < coin->symbols.size; j++) lengths[coin->symbols.data[j]]++;
      }
    }

    cleanup_coins(coins, coinmem);
    lodepng_free(coins);
    cleanup_coins(prev_row, coinmem);
    lodepng_free(prev_row);
  }

  return error;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movl $0x0, -0x44(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x1474
movl $0x50, -0x4(%rbp)
jmp 0x1830
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpq -0x20(%rbp), %rax
jae 0x14bc
movq -0x18(%rbp), %rax
movl -0x28(%rbp), %ecx
cmpl $0x0, (%rax,%rcx,4)
jbe 0x14af
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movl -0x28(%rbp), %ecx
movl (%rax,%rcx,4), %eax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x14b1
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x147b
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpq -0x20(%rbp), %rax
jae 0x14e5
movq -0x10(%rbp), %rax
movl -0x28(%rbp), %ecx
movl $0x0, (%rax,%rcx,4)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x14c3
cmpq $0x0, -0x40(%rbp)
jne 0x1506
movq -0x10(%rbp), %rax
movl $0x1, 0x4(%rax)
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
jmp 0x182a
cmpq $0x1, -0x40(%rbp)
jne 0x156a
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpq -0x20(%rbp), %rax
jae 0x1565
movq -0x18(%rbp), %rax
movl -0x28(%rbp), %ecx
cmpl $0x0, (%rax,%rcx,4)
je 0x1558
movq -0x10(%rbp), %rax
movl -0x28(%rbp), %ecx
movl $0x1, (%rax,%rcx,4)
movq -0x10(%rbp), %rax
movl -0x28(%rbp), %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovel %edx, %ecx
movslq %ecx, %rcx
movl $0x1, (%rax,%rcx,4)
jmp 0x1565
jmp 0x155a
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x1514
jmp 0x1828
movq -0x40(%rbp), %rax
shlq %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
shlq $0x5, %rdi
callq 0x13a0
movq %rax, -0x50(%rbp)
movq -0x68(%rbp), %rdi
shlq $0x5, %rdi
callq 0x13a0
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x15a5
cmpq $0x0, -0x58(%rbp)
jne 0x15c3
movq -0x50(%rbp), %rdi
callq 0x1840
movq -0x58(%rbp), %rdi
callq 0x1840
movl $0x53, -0x4(%rbp)
jmp 0x1830
movq -0x50(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x1860
movq -0x58(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x1860
movq -0x50(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rax
movl %eax, %edx
movq -0x38(%rbp), %rcx
callq 0x18b0
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rsi
movl $0x20, %edx
leaq 0x38d(%rip), %rcx       # 0x19a0
callq 0x1050
cmpl $0x0, -0x44(%rbp)
jne 0x177c
movl $0x0, -0x6c(%rbp)
movl $0x1, -0x2c(%rbp)
movl -0x2c(%rbp), %ecx
xorl %eax, %eax
cmpl -0x24(%rbp), %ecx
movb %al, -0x89(%rbp)
ja 0x164f
cmpl $0x0, -0x44(%rbp)
setne %al
xorb $-0x1, %al
movb %al, -0x89(%rbp)
movb -0x89(%rbp), %al
testb $0x1, %al
jne 0x165e
jmp 0x177a
movq -0x58(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x50(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x70(%rbp)
movq -0x60(%rbp), %rax
movl %eax, -0x6c(%rbp)
movl -0x70(%rbp), %eax
movq %rax, -0x60(%rbp)
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x1a00
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x1860
movq $0x0, -0x60(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
cmpl -0x6c(%rbp), %eax
jae 0x171a
movq -0x50(%rbp), %rax
movq -0x60(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x60(%rbp)
shlq $0x5, %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
movq -0x58(%rbp), %rsi
movl -0x28(%rbp), %eax
shlq $0x5, %rax
addq %rax, %rsi
callq 0x1a50
movq -0x80(%rbp), %rdi
movq -0x58(%rbp), %rsi
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, %eax
shlq $0x5, %rax
addq %rax, %rsi
callq 0x1a90
movl -0x28(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x28(%rbp)
jmp 0x16b3
movl -0x2c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x1753
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rax
movl %eax, %edx
movq -0x38(%rbp), %rcx
callq 0x18b0
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rsi
movl $0x20, %edx
leaq 0x239(%rip), %rcx       # 0x19a0
callq 0x1050
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1630
jmp 0x177c
cmpl $0x0, -0x44(%rbp)
jne 0x17fc
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x40(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x17fa
movq -0x50(%rbp), %rax
movl -0x28(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x88(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x17ed
movq -0x10(%rbp), %rax
movq -0x88(%rbp), %rcx
movq (%rcx), %rcx
movl -0x2c(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x17b5
jmp 0x17ef
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x1789
jmp 0x17fc
movq -0x50(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x1a00
movq -0x50(%rbp), %rdi
callq 0x1840
movq -0x58(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x1a00
movq -0x58(%rbp), %rdi
callq 0x1840
jmp 0x182a
movl -0x44(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax)