user: Converte this assembly snippet into its equivalent C code:

```asm
<inflate>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x688,%rsp
  mov    %rdi,%r13
  mov    %rsi,%r12
  mov    %rdx,%r14
  mov    %fs:0x28,%rax
  mov    %rax,0x678(%rsp)
  xor    %eax,%eax
  lea    0x30(%rsp),%rax
  mov    %rax,0x20(%rsp)
  lea    0x530(%rsp),%rax
  mov    %rax,0x28(%rsp)
  lea    0x550(%rsp),%rax
  mov    %rax,0x10(%rsp)
  lea    0x650(%rsp),%r15
  jmp    L181
L15:
  lea    0xb0(%rsp),%rcx
  mov    0x20(%rsp),%r9
  mov    0x28(%rsp),%r8
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <get_tables@plt>
  test   %rax,%rax
  jns    L140
  mov    $0xffffffff,%eax
  jmp    L117
L64:
  lea    0xb0(%rsp),%rdx
  mov    $0xf,%ecx
  mov    $0x120,%esi
  mov    0x10(%rsp),%rdi
  call   <make_code_table@plt>
  lea    0x530(%rsp),%rax
  lea    0x54e(%rsp),%rdx
L96:
  movb   $0x5,(%rax)
  add    $0x1,%rax
  cmp    %rax,%rdx
  jne    L96
  mov    $0xf,%ecx
  mov    0x20(%rsp),%rdx
  mov    $0x1e,%esi
  mov    0x28(%rsp),%rdi
  call   <make_code_table@plt>
L140:
  lea    0xb0(%rsp),%rcx
  sub    $0x8,%rsp
  push   %r14
  mov    0x30(%rsp),%r9
  mov    0x38(%rsp),%r8
  mov    0x20(%rsp),%rdx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <get_data@plt>
  add    $0x10,%rsp
  test   %rax,%rax
  js     L93
L65:
  cmpb   $0x0,0x18(%rsp)
  jne    L164
L181:
  mov    $0x1,%edx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <read_bits@plt>
  mov    %rax,0x18(%rsp)
  mov    $0x2,%edx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <read_bits@plt>
  lea    -0x1(%rax),%edx
  cmp    $0x1,%dl
  ja     L125
  lea    0x5e0(%rsp),%rcx
  mov    0x10(%rsp),%rsi
  mov    %rsi,%rdx
  cmp    $0x2,%al
  je     L15
L171:
  movb   $0x8,(%rdx)
  add    $0x1,%rdx
  cmp    %rcx,%rdx
  jne    L171
  lea    0x5e0(%rsp),%rax
L143:
  movb   $0x9,(%rax)
  add    $0x1,%rax
  cmp    %r15,%rax
  jne    L143
  lea    0x650(%rsp),%rax
  mov    0x10(%rsp),%rsi
  lea    0x118(%rsi),%rdx
L83:
  movb   $0x7,(%rax)
  add    $0x1,%rax
  cmp    %rax,%rdx
  jne    L83
  lea    0x668(%rsp),%rax
  mov    0x10(%rsp),%rbx
  lea    0x120(%rbx),%rdx
L123:
  movb   $0x8,(%rax)
  add    $0x1,%rax
  cmp    %rdx,%rax
  jne    L123
  jmp    L64
L125:
  test   %al,%al
  jne    L151
  mov    (%r12),%rdx
  lea    0xe(%rdx),%rax
  add    $0x7,%rdx
  cmovns %rdx,%rax
  sar    $0x3,%rax
  mov    %rax,(%r12)
  mov    $0x10,%edx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <read_bits@plt>
  mov    %rax,%rbx
  mov    %eax,0xc(%rsp)
  mov    $0x10,%edx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <read_bits@plt>
  test   %ebx,%ebx
  je     L65
  mov    $0x0,%ebp
L34:
  mov    $0x8,%edx
  mov    %r12,%rsi
  mov    %r13,%rdi
  call   <read_bits@plt>
  movzbl %al,%ebx
  mov    %ebx,%edi
  call   <pushout@plt>
  mov    %ebx,%edi
  call   *%r14
  add    $0x1,%ebp
  cmp    %ebp,0xc(%rsp)
  jne    L34
  jmp    L65
L164:
  mov    $0x0,%eax
L117:
  mov    0x678(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L186
  add    $0x688,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L93:
  mov    $0xffffffff,%eax
  jmp    L117
L151:
  mov    $0xffffffff,%eax
  jmp    L117
L186:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int inflate(const unsigned char *data, long *p, void (*callback)(unsigned char d)) {
  char blast, btype;
  char hlit_size_table[288];
  unsigned int hlit_code_table[288];
  char hdist_size_table[30];
  unsigned int hdist_code_table[30];
again:
  blast = read_bits(data, p, 1);
  btype = read_bits(data, p, 2);
  if (btype == 1 || btype == 2) {
    if (btype == 2) {
      if (get_tables(data, p, hlit_size_table, hlit_code_table, hdist_size_table, hdist_code_table) < 0)
        return -1;
    } else {
      int j;
      for (j = 0; j < 144; j++)
        hlit_size_table[j] = 8;
      for (; j < 256; j++)
        hlit_size_table[j] = 9;
      for (; j < 280; j++)
        hlit_size_table[j] = 7;
      for (; j < 288; j++)
        hlit_size_table[j] = 8;
      make_code_table(hlit_size_table, 288, hlit_code_table, 15);
      for (j = 0; j < 30; j++)
        hdist_size_table[j] = 5;
      make_code_table(hdist_size_table, 30, hdist_code_table, 15);
    }
    if (get_data(data, p, hlit_size_table, hlit_code_table, hdist_size_table, hdist_code_table, callback) < 0)
      return -1;
    ;
  } else if (btype == 0) {
    unsigned int len, nlen;
    unsigned int l;
    unsigned char b;
    *p = (*p + 7) / 8;
    len = read_bits(data, p, 16);
    nlen = read_bits(data, p, 16);
    for (l = 0; l < len; l++) {
      b = read_bits(data, p, 8);
      pushout(b);
      callback(b);
    }
  } else {
    return -1;
  }
  if (!blast)
    goto again;
  return 0;
}
```