user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<ZopfliLengthsToSymbols>:
  endbr64
  push   %r15
  lea    0x1(%rdx),%r15d
  push   %r14
  push   %r13
  mov    %rsi,%r13
  push   %r12
  mov    %edx,%r12d
  push   %rbp
  lea    0x0(,%r15,8),%ebp
  push   %rbx
  mov    %rdi,%rbx
  mov    %ebp,%edi
  sub    $0x18,%rsp
  mov    %rcx,0x8(%rsp)
  call   <malloc@plt>
  mov    %ebp,%edi
  mov    %rax,%r14
  call   <malloc@plt>
  mov    %rax,(%rsp)
  test   %r13,%r13
  je     L128
  xor    %edx,%edx
  xor    %eax,%eax
  nopw   0x0(%rax,%rax,1)
L68:
  mov    0x8(%rsp),%rsi
  movl   $0x0,(%rsi,%rax,4)
  lea    0x1(%rdx),%eax
  mov    %rax,%rdx
  cmp    %r13,%rax
  jb     L68
L128:
  lea    -0x6(%r12),%eax
  cmp    $0xfffffff8,%eax
  ja     L9
  lea    -0x1(%r12),%eax
  mov    %r14,%rcx
  pxor   %xmm0,%xmm0
  xor    %edx,%edx
  shr    %eax
  add    $0x1,%eax
  nopl   0x0(%rax,%rax,1)
L46:
  add    $0x1,%edx
  movups %xmm0,(%rcx)
  add    $0x10,%rcx
  cmp    %eax,%edx
  jb     L46
  add    %eax,%eax
  cmp    %eax,%r15d
  je     L11
  movq   $0x0,(%r14,%rax,8)
L11:
  test   %r13,%r13
  je     L31
L67:
  xor    %r15d,%r15d
  xor    %eax,%eax
  nopl   0x0(%rax,%rax,1)
L141:
  lea    (%rbx,%rax,4),%rbp
  xor    %edi,%edi
  cmp    %r12d,0x0(%rbp)
  setbe  %dil
  call   <assert@plt>
  mov    0x0(%rbp),%eax
  addq   $0x1,(%r14,%rax,8)
  lea    0x1(%r15),%eax
  mov    %rax,%r15
  cmp    %r13,%rax
  jb     L141
  movq   $0x0,(%r14)
  test   %r12d,%r12d
  je     L106
L137:
  mov    %r14,%rcx
  xor    %eax,%eax
  mov    $0x1,%edx
  nopl   (%rax)
L136:
  add    (%rcx),%eax
  mov    (%rsp),%rsi
  mov    %edx,%edi
  add    $0x1,%edx
  lea    (%rax,%rax,1),%r8d
  add    $0x8,%rcx
  mov    %r8,(%rsi,%rdi,8)
  mov    %r8,%rax
  cmp    %edx,%r12d
  jae    L136
  test   %r13,%r13
  je     L148
L106:
  xor    %ecx,%ecx
  xor    %eax,%eax
  nopl   0x0(%rax,%rax,1)
L40:
  mov    (%rbx,%rax,4),%edx
  test   %edx,%edx
  je     L51
  mov    (%rsp),%rdi
  lea    (%rdi,%rdx,8),%rsi
  mov    0x8(%rsp),%rdi
  mov    (%rsi),%rdx
  mov    %edx,(%rdi,%rax,4)
  add    $0x1,%rdx
  mov    %rdx,(%rsi)
L51:
  lea    0x1(%rcx),%eax
  mov    %rax,%rcx
  cmp    %r13,%rax
  jb     L40
L148:
  mov    %r14,%rdi
  call   <free@plt>
  mov    (%rsp),%rdi
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1070 <free@plt>
  nopl   0x0(%rax,%rax,1)
L9:
  xor    %eax,%eax
  nopw   0x0(%rax,%rax,1)
L135:
  mov    %eax,%edx
  add    $0x1,%eax
  movq   $0x0,(%r14,%rdx,8)
  cmp    %eax,%r12d
  jae    L135
  test   %r13,%r13
  jne    L67
  nopl   0x0(%rax,%rax,1)
L31:
  movq   $0x0,(%r14)
  test   %r12d,%r12d
  jne    L137
  jmp    L148
```

assistant: ```c
void ZopfliLengthsToSymbols(const unsigned *lengths, size_t n, unsigned maxbits, unsigned *symbols) {
  size_t *bl_count = (size_t *)malloc(sizeof(size_t) * (maxbits + 1));
  size_t *next_code = (size_t *)malloc(sizeof(size_t) * (maxbits + 1));
  unsigned bits, i;
  unsigned code;
  for (i = 0; i < n; i++) {
    symbols[i] = 0;
  }
  for (bits = 0; bits <= maxbits; bits++) {
    bl_count[bits] = 0;
  }
  for (i = 0; i < n; i++) {
    assert(lengths[i] <= maxbits);
    bl_count[lengths[i]]++;
  }
  code = 0;
  bl_count[0] = 0;
  for (bits = 1; bits <= maxbits; bits++) {
    code = (code + bl_count[bits - 1]) << 1;
    next_code[bits] = code;
  }
  for (i = 0; i < n; i++) {
    unsigned len = lengths[i];
    if (len != 0) {
      symbols[i] = next_code[len];
      next_code[len]++;
    }
  }
  free(bl_count);
  free(next_code);
}
```