user: 请从给定的汇编指令推导出C源代码：

```asm
<img_rle_compact>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %esi,-0x3c(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %ecx,-0x40(%rbp)
  mov    %r8d,-0x4c(%rbp)
  cmpl   $0x1,-0x3c(%rbp)
  jne    L277
  cmpl   $0x1,-0x40(%rbp)
  jne    L277
  mov    -0x38(%rbp),%rbx
  mov    -0x4c(%rbp),%eax
  cltq
  lea    (%rbx,%rax,1),%r15
  mov    -0x48(%rbp),%r12
  jmp    L643
L311:
  mov    %rbx,%rdi
  add    $0x2,%rbx
  jmp    L156
L257:
  add    $0x1,%rbx
L156:
  cmp    %r15,%rbx
  jae    L710
  lea    -0x2(%rbx),%rax
  movzbl (%rax),%edx
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    %al,%dl
  jne    L257
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%edx
  movzbl (%rbx),%eax
  cmp    %al,%dl
  jne    L257
L710:
  sub    $0x2,%rbx
  mov    %rbx,%rax
  sub    %rdi,%rax
  mov    %eax,%r13d
  jmp    L641
L544:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r14d,%edx
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  or     $0xffffff80,%edx
  mov    %dl,(%rax)
  jmp    L2
L432:
  mov    %rdi,%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,%rdi
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
L2:
  mov    %r14d,%eax
  lea    -0x1(%rax),%r14d
  test   %ax,%ax
  jne    L432
L641:
  test   %r13d,%r13d
  jne    L544
  mov    %rbx,%rdi
  mov    %rbx,%rax
  lea    0x1(%rax),%rbx
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%ecx
  jmp    L582
L529:
  add    $0x1,%rbx
L582:
  cmp    %r15,%rbx
  jae    L196
  movzbl (%rbx),%eax
  movzbl %al,%eax
  cmp    %ax,%cx
  je     L529
L196:
  mov    %rbx,%rax
  sub    %rdi,%rax
  mov    %eax,%r13d
  jmp    L295
L495:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  mov    %r14d,%edx
  mov    %dl,(%rax)
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  mov    %ecx,%edx
  mov    %dl,(%rax)
L295:
  test   %r13d,%r13d
  jne    L495
L643:
  cmp    %r15,%rbx
  jb     L311
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movb   $0x0,(%rax)
  mov    %r12,%rax
  sub    -0x48(%rbp),%rax
  jmp    L210
L277:
  cmpl   $0x1,-0x3c(%rbp)
  jne    L519
  cmpl   $0x2,-0x40(%rbp)
  jne    L519
  mov    -0x38(%rbp),%rbx
  mov    -0x4c(%rbp),%eax
  cltq
  lea    (%rbx,%rax,1),%r15
  mov    -0x48(%rbp),%r12
  jmp    L613
L219:
  mov    %rbx,%rcx
  add    $0x2,%rbx
  jmp    L171
L698:
  add    $0x1,%rbx
L171:
  cmp    %r15,%rbx
  jae    L105
  lea    -0x2(%rbx),%rax
  movzbl (%rax),%edx
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    %al,%dl
  jne    L698
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%edx
  movzbl (%rbx),%eax
  cmp    %al,%dl
  jne    L698
L105:
  sub    $0x2,%rbx
  mov    %rbx,%rax
  sub    %rcx,%rax
  mov    %eax,%r13d
  jmp    L503
L300:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  mov    %r14d,%edx
  or     $0x80,%dl
  mov    %dx,(%rax)
  jmp    L203
L52:
  mov    %rcx,%rax
  lea    0x1(%rax),%rsi
  mov    %rsi,%rcx
  movzbl (%rax),%edx
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  movzbl %dl,%edx
  mov    %dx,(%rax)
L203:
  mov    %r14d,%eax
  lea    -0x1(%rax),%r14d
  test   %ax,%ax
  jne    L52
L503:
  test   %r13d,%r13d
  jne    L300
  mov    %rbx,%rcx
  mov    %rbx,%rax
  lea    0x1(%rax),%rbx
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%esi
  jmp    L104
L6:
  add    $0x1,%rbx
L104:
  cmp    %r15,%rbx
  jae    L31
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %esi,%edi
  cmp    %ax,%di
  je     L6
L31:
  mov    %rbx,%rax
  sub    %rcx,%rax
  mov    %eax,%r13d
  jmp    L4
L626:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  mov    %r14w,(%rax)
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  mov    %esi,%ecx
  mov    %cx,(%rax)
L4:
  test   %r13d,%r13d
  jne    L626
L613:
  cmp    %r15,%rbx
  jb     L219
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  movw   $0x0,(%rax)
  mov    %r12,%rax
  sub    -0x48(%rbp),%rax
  sar    %rax
  jmp    L210
L519:
  cmpl   $0x2,-0x3c(%rbp)
  jne    L338
  cmpl   $0x1,-0x40(%rbp)
  jne    L338
  mov    -0x38(%rbp),%rbx
  mov    -0x4c(%rbp),%eax
  cltq
  add    %rax,%rax
  lea    (%rbx,%rax,1),%r15
  mov    -0x48(%rbp),%r12
  jmp    L347
L390:
  mov    %rbx,%rsi
  add    $0x4,%rbx
  jmp    L185
L262:
  add    $0x2,%rbx
L185:
  cmp    %r15,%rbx
  jae    L93
  lea    -0x4(%rbx),%rax
  movzwl (%rax),%edx
  lea    -0x2(%rbx),%rax
  movzwl (%rax),%eax
  cmp    %ax,%dx
  jne    L262
  lea    -0x2(%rbx),%rax
  movzwl (%rax),%edx
  movzwl (%rbx),%eax
  cmp    %ax,%dx
  jne    L262
L93:
  sub    $0x4,%rbx
  mov    %rbx,%rax
  sub    %rsi,%rax
  sar    %rax
  mov    %eax,%r13d
  jmp    L532
L661:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r14d,%edx
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  or     $0xffffff80,%edx
  mov    %dl,(%rax)
  jmp    L477
L487:
  mov    %rsi,%rax
  lea    0x2(%rax),%rsi
  movzwl (%rax),%edx
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  mov    %dl,(%rax)
L477:
  mov    %r14d,%eax
  lea    -0x1(%rax),%r14d
  test   %ax,%ax
  jne    L487
L532:
  test   %r13d,%r13d
  jne    L661
  mov    %rbx,%rsi
  mov    %rbx,%rax
  lea    0x2(%rax),%rbx
  movzwl (%rax),%eax
  mov    %eax,%ecx
  jmp    L355
L534:
  add    $0x2,%rbx
L355:
  cmp    %r15,%rbx
  jae    L443
  movzwl (%rbx),%eax
  mov    %ecx,%edi
  cmp    %ax,%di
  je     L534
L443:
  mov    %rbx,%rax
  sub    %rsi,%rax
  sar    %rax
  mov    %eax,%r13d
  jmp    L74
L121:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  mov    %r14d,%edx
  mov    %dl,(%rax)
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  mov    %ecx,%edx
  mov    %dl,(%rax)
L74:
  test   %r13d,%r13d
  jne    L121
L347:
  cmp    %r15,%rbx
  jb     L390
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movb   $0x0,(%rax)
  mov    %r12,%rax
  sub    -0x48(%rbp),%rax
  jmp    L210
L338:
  cmpl   $0x2,-0x3c(%rbp)
  jne    L265
  cmpl   $0x2,-0x40(%rbp)
  jne    L265
  mov    -0x38(%rbp),%rbx
  mov    -0x4c(%rbp),%eax
  cltq
  add    %rax,%rax
  lea    (%rbx,%rax,1),%r15
  mov    -0x48(%rbp),%r12
  jmp    L438
L528:
  mov    %rbx,%rdi
  add    $0x4,%rbx
  jmp    L707
L629:
  add    $0x2,%rbx
L707:
  cmp    %r15,%rbx
  jae    L488
  lea    -0x4(%rbx),%rax
  movzwl (%rax),%edx
  lea    -0x2(%rbx),%rax
  movzwl (%rax),%eax
  cmp    %ax,%dx
  jne    L629
  lea    -0x2(%rbx),%rax
  movzwl (%rax),%edx
  movzwl (%rbx),%eax
  cmp    %ax,%dx
  jne    L629
L488:
  sub    $0x4,%rbx
  mov    %rbx,%rax
  sub    %rdi,%rax
  sar    %rax
  mov    %eax,%r13d
  jmp    L314
L319:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  mov    %r14d,%edx
  or     $0x80,%dl
  mov    %dx,(%rax)
  jmp    L221
L40:
  mov    %rdi,%rdx
  lea    0x2(%rdx),%rax
  mov    %rax,%rdi
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  movzwl (%rdx),%edx
  mov    %dx,(%rax)
L221:
  mov    %r14d,%eax
  lea    -0x1(%rax),%r14d
  test   %ax,%ax
  jne    L40
L314:
  test   %r13d,%r13d
  jne    L319
  mov    %rbx,%rdi
  mov    %rbx,%rax
  lea    0x2(%rax),%rbx
  movzwl (%rax),%eax
  mov    %eax,%esi
  jmp    L82
L557:
  add    $0x2,%rbx
L82:
  cmp    %r15,%rbx
  jae    L342
  movzwl (%rbx),%eax
  mov    %esi,%ecx
  cmp    %ax,%cx
  je     L557
L342:
  mov    %rbx,%rax
  sub    %rdi,%rax
  sar    %rax
  mov    %eax,%r13d
  jmp    L677
L197:
  mov    $0x7e,%eax
  cmp    %eax,%r13d
  cmovle %r13d,%eax
  mov    %eax,%r14d
  movzwl %r14w,%eax
  sub    %eax,%r13d
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  mov    %r14w,(%rax)
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  mov    %si,(%rax)
L677:
  test   %r13d,%r13d
  jne    L197
L438:
  cmp    %r15,%rbx
  jb     L528
  mov    %r12,%rax
  lea    0x2(%rax),%r12
  movw   $0x0,(%rax)
  mov    %r12,%rax
  sub    -0x48(%rbp),%rax
  sar    %rax
  jmp    L210
L265:
  mov    -0x40(%rbp),%edx
  mov    -0x3c(%rbp),%eax
  mov    %eax,%esi
  lea    D2(%rip),%rax
  mov    %rax,%rdi
  call   <i_errhdlr@plt>
  mov    $0x0,%eax
L210:
  add    $0x28,%rsp
  pop    %rbx
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  pop    %rbp
  ret
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D2
type: string

tool: D2: rle_compact: bad bpp: %d %d


assistant: ```c
int img_rle_compact(unsigned short *expbuf, int ibpp, unsigned short *rlebuf, int obpp, int cnt) {
  if (ibpp == 1 && obpp == 1) {
    register unsigned char *iptr = (unsigned char *)expbuf;
    register unsigned char *ibufend = iptr + cnt;
    register unsigned char *sptr;
    register unsigned char *optr = (unsigned char *)rlebuf;
    register unsigned short todo, cc;
    register int count;
    while (iptr < ibufend) {
      sptr = iptr;
      iptr += 2;
      while ((iptr < ibufend) && ((iptr[-2] != iptr[-1]) || (iptr[-1] != iptr[0])))
        iptr++;
      iptr -= 2;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = 0x80 | todo;
        while (todo--)
          *optr++ = *sptr++;
      }
      sptr = iptr;
      cc = *iptr++;
      while ((iptr < ibufend) && (*iptr == cc))
        iptr++;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = todo;
        *optr++ = cc;
      }
    }
    *optr++ = 0;
    ;
    return optr - (unsigned char *)rlebuf;
  } else if (ibpp == 1 && obpp == 2) {
    register unsigned char *iptr = (unsigned char *)expbuf;
    register unsigned char *ibufend = iptr + cnt;
    register unsigned char *sptr;
    register unsigned short *optr = rlebuf;
    register unsigned short todo, cc;
    register int count;
    while (iptr < ibufend) {
      sptr = iptr;
      iptr += 2;
      while ((iptr < ibufend) && ((iptr[-2] != iptr[-1]) || (iptr[-1] != iptr[0])))
        iptr++;
      iptr -= 2;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = 0x80 | todo;
        while (todo--)
          *optr++ = *sptr++;
      }
      sptr = iptr;
      cc = *iptr++;
      while ((iptr < ibufend) && (*iptr == cc))
        iptr++;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = todo;
        *optr++ = cc;
      }
    }
    *optr++ = 0;
    ;
    return optr - rlebuf;
  } else if (ibpp == 2 && obpp == 1) {
    register unsigned short *iptr = expbuf;
    register unsigned short *ibufend = iptr + cnt;
    register unsigned short *sptr;
    register unsigned char *optr = (unsigned char *)rlebuf;
    register unsigned short todo, cc;
    register int count;
    while (iptr < ibufend) {
      sptr = iptr;
      iptr += 2;
      while ((iptr < ibufend) && ((iptr[-2] != iptr[-1]) || (iptr[-1] != iptr[0])))
        iptr++;
      iptr -= 2;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = 0x80 | todo;
        while (todo--)
          *optr++ = *sptr++;
      }
      sptr = iptr;
      cc = *iptr++;
      while ((iptr < ibufend) && (*iptr == cc))
        iptr++;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = todo;
        *optr++ = cc;
      }
    }
    *optr++ = 0;
    ;
    return optr - (unsigned char *)rlebuf;
  } else if (ibpp == 2 && obpp == 2) {
    register unsigned short *iptr = expbuf;
    register unsigned short *ibufend = iptr + cnt;
    register unsigned short *sptr;
    register unsigned short *optr = rlebuf;
    register unsigned short todo, cc;
    register int count;
    while (iptr < ibufend) {
      sptr = iptr;
      iptr += 2;
      while ((iptr < ibufend) && ((iptr[-2] != iptr[-1]) || (iptr[-1] != iptr[0])))
        iptr++;
      iptr -= 2;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = 0x80 | todo;
        while (todo--)
          *optr++ = *sptr++;
      }
      sptr = iptr;
      cc = *iptr++;
      while ((iptr < ibufend) && (*iptr == cc))
        iptr++;
      count = iptr - sptr;
      while (count) {
        todo = count > 126 ? 126 : count;
        count -= todo;
        *optr++ = todo;
        *optr++ = cc;
      }
    }
    *optr++ = 0;
    ;
    return optr - rlebuf;
  } else {
    i_errhdlr("rle_compact: bad bpp: %d %d\n", ibpp, obpp);
    return 0;
  }
}
```