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

```asm
<type_lzw>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rsi,0x8(%rsp)
  mov    %edi,%eax
  shl    $0x5,%eax
  lea    0x130(%rax),%eax
  cmp    %eax,%ecx
  jb     L28
  mov    %edi,%r14d
  mov    %rdx,%rbp
  mov    %rcx,%rdx
  mov    %eax,%eax
  movzbl -0xe(%rbp,%rax,1),%r12d
  shl    $0x8,%r12d
  movzbl -0xf(%rbp,%rax,1),%ecx
  shl    $0x10,%ecx
  or     %ecx,%r12d
  movzbl -0xd(%rbp,%rax,1),%ecx
  or     %ecx,%r12d
  movzbl -0x10(%rbp,%rax,1),%ecx
  shl    $0x18,%ecx
  or     %ecx,%r12d
  movzbl -0x6(%rbp,%rax,1),%ebx
  shl    $0x8,%ebx
  movzbl -0x7(%rbp,%rax,1),%ecx
  shl    $0x10,%ecx
  or     %ecx,%ebx
  movzbl -0x5(%rbp,%rax,1),%ecx
  or     %ecx,%ebx
  movzbl -0x8(%rbp,%rax,1),%ecx
  shl    $0x18,%ecx
  or     %ecx,%ebx
  lea    (%r12,%rbx,1),%ecx
  cmp    %edx,%ecx
  jbe    L53
L28:
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L53:
  movzbl -0xb(%rbp,%rax,1),%r13d
  shl    $0x10,%r13d
  movzbl -0xc(%rbp,%rax,1),%edx
  shl    $0x18,%edx
  or     %edx,%r13d
  movzbl -0x9(%rbp,%rax,1),%edx
  or     %edx,%r13d
  movzbl -0xa(%rbp,%rax,1),%eax
  shl    $0x8,%eax
  or     %eax,%r13d
  mov    %r13d,%edi
  call   <malloc@plt>
  mov    %rax,0x10(%rsp)
  test   %rax,%rax
  je     L28
  mov    %r14d,%esi
  lea    D47(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    %r12d,%esi
  lea    D28(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    %r13d,%esi
  lea    D14(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    %ebx,%esi
  lea    D10(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  test   %r13d,%r13d
  je     L184
  mov    %ebx,%ebx
  add    %rbp,%rbx
  movl   $0x0,0x1c(%rsp)
  mov    $0x0,%r14d
L188:
  mov    %r14d,%eax
  mov    $0x1,%edi
  sub    %r14d,%edi
L57:
  lea    (%rdi,%rax,1),%esi
  mov    %eax,%edx
  shr    $0x3,%edx
  cmp    %r12d,%edx
  jae    L94
  mov    %edx,%edx
  movzbl (%rbx,%rdx,1),%ecx
  mov    %eax,%edx
  not    %edx
  and    $0x7,%edx
  add    $0x1,%eax
  bt     %edx,%ecx
  jb     L57
  mov    $0x1,%r15d
  mov    %esi,%ecx
  shl    %cl,%r15d
  sub    $0x2,%r15d
  jmp    L65
L161:
  mov    %r14d,%eax
L65:
  sub    $0x1,%esi
  mov    %eax,%edx
  shr    $0x3,%edx
  cmp    %r12d,%edx
  jae    L94
  lea    0x1(%rax),%r14d
  mov    %edx,%edx
  movzbl (%rbx,%rdx,1),%edx
  mov    %eax,%ecx
  not    %ecx
  and    $0x7,%ecx
  sar    %cl,%edx
  and    $0x1,%edx
  mov    %esi,%ecx
  shl    %cl,%edx
  add    %edx,%r15d
  test   %esi,%esi
  jne    L161
  cmp    $0xff,%r15d
  ja     L167
  lea    0x10(%r15),%eax
  movzbl 0x0(%rbp,%rax,1),%edx
  mov    0x1c(%rsp),%edi
  mov    %edi,%eax
  mov    0x10(%rsp),%rsi
  mov    %dl,(%rsi,%rax,1)
  lea    0x1(%rdi),%eax
  mov    %eax,0x1c(%rsp)
L187:
  cmp    %r13d,0x1c(%rsp)
  jb     L188
L184:
  lea    D34(%rip),%rdi
  call   <puts@plt>
  mov    0x8(%rsp),%rcx
  mov    %r13d,%edx
  mov    $0x1,%esi
  mov    0x10(%rsp),%rdi
  call   <fwrite@plt>
L94:
  mov    0x10(%rsp),%rdi
  call   <free@plt>
  jmp    L28
L167:
  mov    %r14d,%esi
  sub    %eax,%esi
  mov    %r14d,%edx
  shr    $0x3,%edx
  cmp    %r12d,%edx
  jae    L94
  mov    %edx,%edx
  movzbl (%rbx,%rdx,1),%ecx
  mov    %r14d,%edx
  not    %edx
  and    $0x7,%edx
  add    $0x1,%r14d
  bt     %edx,%ecx
  jb     L167
  mov    $0x1,%edx
  mov    %esi,%ecx
  shl    %cl,%edx
  sub    $0x2,%edx
L107:
  sub    $0x1,%esi
  mov    %r14d,%eax
  shr    $0x3,%eax
  cmp    %r12d,%eax
  jae    L94
  mov    %eax,%eax
  movzbl (%rbx,%rax,1),%eax
  mov    %r14d,%ecx
  not    %ecx
  and    $0x7,%ecx
  sar    %cl,%eax
  and    $0x1,%eax
  add    $0x1,%r14d
  mov    %esi,%ecx
  shl    %cl,%eax
  add    %eax,%edx
  test   %esi,%esi
  jne    L107
  lea    -0x100(%r15),%eax
  mov    0x1c(%rsp),%ecx
  cmp    %ecx,%eax
  ja     L94
  lea    0x3(%rdx),%edi
  mov    %r13d,%esi
  sub    %ecx,%esi
  call   <min@plt>
  mov    0x1c(%rsp),%ecx
  add    %eax,%ecx
  mov    $0x100,%esi
  sub    %r15d,%esi
L145:
  mov    0x1c(%rsp),%edi
  lea    (%rsi,%rdi,1),%eax
  mov    0x10(%rsp),%r8
  movzbl (%r8,%rax,1),%edx
  mov    %edi,%eax
  mov    %dl,(%r8,%rax,1)
  add    $0x1,%edi
  mov    %edi,0x1c(%rsp)
  cmp    %ecx,%edi
  jne    L145
  mov    %ecx,0x1c(%rsp)
  jmp    L187
```

tool_calls: name: read_data
arguments: data_label: D47
datatype: string
name: read_data
arguments: data_label: D28
datatype: string
name: read_data
arguments: data_label: D14
datatype: string
name: read_data
arguments: data_label: D10
datatype: string
name: read_data
arguments: data_label: D34
datatype: string

tool: D47: * number  : %.x


tool: D28: * arcsize : %.x


tool: D14: * datasize: %.x


tool: D10: * postion : %.x


tool: D34: * solve succeed.

assistant: ```c
void type_lzw(unsigned int number, FILE *fp, unsigned char *ptr, size_t size) {
  const unsigned char *src;
  unsigned int srcsize;
  unsigned int pos;
  unsigned int arcsize;
  unsigned int dstsize;
  unsigned int arcpos;
  const unsigned char *arc;
  unsigned int apos;
  unsigned int dpos;
  unsigned int bitcnt;
  unsigned int bitdat;
  unsigned int datum;
  unsigned char *dst;
  unsigned int leng;
  src = ptr;
  srcsize = size;
  pos = 0x110 + ((number + 1) * 32);
  if (pos > srcsize) {
    goto lzhsolve_err1;
  }
  arcsize = (((unsigned int)(src + pos - 16)[3]) | ((unsigned int)(src + pos - 16)[2] << 8) | ((unsigned int)(src + pos - 16)[1] << 16) | ((unsigned int)(src + pos - 16)[0] << 24));
  dstsize = (((unsigned int)(src + pos - 12)[3]) | ((unsigned int)(src + pos - 12)[2] << 8) | ((unsigned int)(src + pos - 12)[1] << 16) | ((unsigned int)(src + pos - 12)[0] << 24));
  arcpos = (((unsigned int)(src + pos - 8)[3]) | ((unsigned int)(src + pos - 8)[2] << 8) | ((unsigned int)(src + pos - 8)[1] << 16) | ((unsigned int)(src + pos - 8)[0] << 24));
  if ((arcsize + arcpos) > srcsize) {
    goto lzhsolve_err1;
  }
  arc = src + arcpos;
  dst = (unsigned char *)malloc(dstsize);
  if (dst == NULL) {
    goto lzhsolve_err1;
  }
  printf("* number  : %.x\n", number);
  printf("* arcsize : %.x\n", arcsize);
  printf("* datasize: %.x\n", dstsize);
  printf("* postion : %.x\n", arcpos);
  apos = 0;
  dpos = 0;
  while (dpos < dstsize) {
    bitcnt = 0;
    do {
      bitcnt++;
      if ((apos >> 3) >= arcsize) {
        goto lzhsolve_err2;
      }
      bitdat = (arc[apos >> 3] >> ((~apos) & 7)) & 1;
      apos++;
    } while (bitdat);
    datum = (1 << bitcnt) - 2;
    do {
      bitcnt--;
      if ((apos >> 3) >= arcsize) {
        goto lzhsolve_err2;
      }
      bitdat = (arc[apos >> 3] >> ((~apos) & 7)) & 1;
      apos++;
      datum += bitdat << bitcnt;
    } while (bitcnt);
    if (datum < 0x100) {
      dst[dpos++] = src[datum + 0x10];
    } else {
      bitcnt = 0;
      do {
        bitcnt++;
        if ((apos >> 3) >= arcsize) {
          goto lzhsolve_err2;
        }
        bitdat = (arc[apos >> 3] >> ((~apos) & 7)) & 1;
        apos++;
      } while (bitdat);
      leng = (1 << bitcnt) - 2;
      do {
        bitcnt--;
        if ((apos >> 3) >= arcsize) {
          goto lzhsolve_err2;
        }
        bitdat = (arc[apos >> 3] >> ((~apos) & 7)) & 1;
        apos++;
        leng += bitdat << bitcnt;
      } while (bitcnt);
      datum -= 0x100;
      if (dpos < datum) {
        goto lzhsolve_err2;
      }
      leng = min(leng + 3, dstsize - dpos);
      do {
        dst[dpos] = dst[dpos - datum];
        dpos++;
      } while (--leng);
    }
  }
  printf("* solve succeed.\n");
  fwrite(dst, 1, dstsize, fp);
lzhsolve_err2:
  free(dst);
lzhsolve_err1:
  return;
}
```