user: Please show me the C implementation that matches the assembly code listed below:

```asm
<type_lzw>:
  endbr64
  push   %r15
  mov    %edi,%eax
  push   %r14
  shl    $0x5,%eax
  push   %r13
  add    $0x130,%eax
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %edi,0x4(%rsp)
  cmp    %eax,%ecx
  jb     L209
  mov    %rdx,%rbx
  mov    %rcx,%rdx
  mov    %rsi,%r14
  movzbl -0xe(%rbx,%rax,1),%r13d
  movzbl -0xf(%rbx,%rax,1),%ecx
  movzbl -0x6(%rbx,%rax,1),%ebp
  movzbl -0x7(%rbx,%rax,1),%r10d
  shl    $0x10,%ecx
  shl    $0x8,%r13d
  movzbl -0x9(%rbx,%rax,1),%edi
  movzbl -0xa(%rbx,%rax,1),%esi
  shl    $0x10,%r10d
  or     %ecx,%r13d
  movzbl -0xd(%rbx,%rax,1),%ecx
  shl    $0x8,%ebp
  or     %r10d,%ebp
  movzbl -0xc(%rbx,%rax,1),%r9d
  movzbl -0x5(%rbx,%rax,1),%r10d
  or     %ecx,%r13d
  movzbl -0x10(%rbx,%rax,1),%ecx
  or     %r10d,%ebp
  shl    $0x18,%ecx
  or     %ecx,%r13d
  movzbl -0xb(%rbx,%rax,1),%ecx
  movzbl -0x8(%rbx,%rax,1),%eax
  shl    $0x18,%eax
  or     %eax,%ebp
  lea    0x0(%r13,%rbp,1),%eax
  cmp    %edx,%eax
  jbe    L79
L209:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L79:
  shl    $0x18,%r9d
  movzbl %cl,%r12d
  shl    $0x8,%esi
  shl    $0x10,%r12d
  or     %r9d,%r12d
  or     %edi,%r12d
  or     %esi,%r12d
  mov    %r12d,%edi
  call   <malloc@plt>
  mov    %rax,%r15
  test   %rax,%rax
  je     L209
  mov    0x4(%rsp),%esi
  lea    D45(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    %r13d,%esi
  lea    D27(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    %r12d,%esi
  lea    D35(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  xor    %eax,%eax
  mov    %ebp,%esi
  lea    D37(%rip),%rdi
  call   <printf@plt>
  test   %r12d,%r12d
  je     L221
  add    %rbx,%rbp
  xor    %r9d,%r9d
  xor    %edx,%edx
  mov    $0x1,%r8d
L21:
  mov    %r8d,%ecx
  mov    %edx,%eax
  sub    %edx,%ecx
  jmp    L191
  nopl   0x0(%rax)
L178:
  movzbl 0x0(%rbp,%rdx,1),%edi
  mov    %eax,%edx
  add    $0x1,%eax
  not    %edx
  and    $0x7,%edx
  bt     %edx,%edi
  jae    L104
L191:
  mov    %eax,%edx
  lea    (%rcx,%rax,1),%esi
  shr    $0x3,%edx
  cmp    %r13d,%edx
  jb     L178
L206:
  add    $0x18,%rsp
  mov    %r15,%rdi
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    10a0 <free@plt>
  nopw   0x0(%rax,%rax,1)
L104:
  mov    %r8d,%r10d
  mov    %esi,%ecx
  shl    %cl,%r10d
  sub    $0x2,%r10d
  jmp    L173
  xchg   %ax,%ax
L6:
  movzbl 0x0(%rbp,%rcx,1),%edi
  mov    %eax,%ecx
  lea    0x1(%rax),%edx
  not    %ecx
  and    $0x7,%ecx
  sar    %cl,%edi
  mov    %esi,%ecx
  and    $0x1,%edi
  shl    %cl,%edi
  add    %edi,%r10d
  test   %esi,%esi
  je     L167
  mov    %edx,%eax
L173:
  mov    %eax,%ecx
  sub    $0x1,%esi
  shr    $0x3,%ecx
  cmp    %r13d,%ecx
  jb     L6
  jmp    L206
L167:
  cmp    $0xff,%r10d
  ja     L229
  lea    0x10(%r10),%eax
  movzbl (%rbx,%rax,1),%ecx
  mov    %r9d,%eax
  add    $0x1,%r9d
  mov    %cl,(%r15,%rax,1)
L9:
  cmp    %r12d,%r9d
  jb     L21
L221:
  lea    D43(%rip),%rdi
  call   <puts@plt>
  mov    %r14,%rcx
  mov    %r12d,%edx
  mov    $0x1,%esi
  mov    %r15,%rdi
  call   <fwrite@plt>
  jmp    L206
  nopl   0x0(%rax)
L211:
  movzbl 0x0(%rbp,%rcx,1),%edi
  mov    %edx,%ecx
  add    $0x1,%edx
  not    %ecx
  and    $0x7,%ecx
  bt     %ecx,%edi
  jae    L33
L229:
  mov    %edx,%ecx
  mov    %edx,%esi
  shr    $0x3,%ecx
  sub    %eax,%esi
  cmp    %r13d,%ecx
  jb     L211
  jmp    L206
L33:
  mov    %r8d,%edi
  mov    %esi,%ecx
  shl    %cl,%edi
  sub    $0x2,%edi
  jmp    L131
  nopl   0x0(%rax,%rax,1)
L227:
  mov    %edx,%ecx
  movzbl 0x0(%rbp,%rax,1),%eax
  add    $0x1,%edx
  not    %ecx
  and    $0x7,%ecx
  sar    %cl,%eax
  mov    %esi,%ecx
  and    $0x1,%eax
  shl    %cl,%eax
  add    %eax,%edi
  test   %esi,%esi
  je     L30
L131:
  mov    %edx,%eax
  sub    $0x1,%esi
  shr    $0x3,%eax
  cmp    %r13d,%eax
  jb     L227
  jmp    L206
L30:
  lea    -0x100(%r10),%eax
  mov    %edx,0xc(%rsp)
  mov    %r10d,0x8(%rsp)
  cmp    %eax,%r9d
  jb     L206
  mov    %r12d,%esi
  add    $0x3,%edi
  mov    %r9d,0x4(%rsp)
  sub    %r9d,%esi
  call   <min@plt>
  mov    0x4(%rsp),%r9d
  mov    0x8(%rsp),%r10d
  mov    $0x100,%esi
  mov    0xc(%rsp),%edx
  mov    $0x1,%r8d
  lea    (%r9,%rax,1),%edi
  sub    %r10d,%esi
  nopl   0x0(%rax)
L68:
  lea    (%rsi,%r9,1),%eax
  movzbl (%r15,%rax,1),%ecx
  mov    %r9d,%eax
  add    $0x1,%r9d
  mov    %cl,(%r15,%rax,1)
  cmp    %edi,%r9d
  jne    L68
  jmp    L9
```

tool_calls: name: parse_data
arguments: label: D45
datatype: string
name: parse_data
arguments: label: D27
datatype: string
name: parse_data
arguments: label: D35
datatype: string
name: parse_data
arguments: label: D37
datatype: string
name: parse_data
arguments: label: D43
datatype: string

tool: D45: * number  : %.x


tool: D27: * arcsize : %.x


tool: D35: * datasize: %.x


tool: D37: * postion : %.x


tool: D43: * 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;
}
```