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

```asm
<bitmap_decompress1>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,-0x30(%rsp)
  movslq %r8d,%r8
  lea    (%rcx,%r8,1),%rax
  mov    %rax,-0x8(%rsp)
  cmp    %rax,%rcx
  jae    L879
  mov    %edx,%r11d
  mov    %rcx,%r9
  mov    %esi,%edx
  movl   $0x0,-0x18(%rsp)
  movl   $0x0,-0x1c(%rsp)
  mov    $0xffffffff,%ebp
  movl   $0x0,-0x20(%rsp)
  mov    $0xffffffff,%r12d
  mov    $0x0,%r13d
  movb   $0x0,-0x25(%rsp)
  mov    $0x0,%edi
  mov    $0x0,%r10d
L336:
  lea    0x1(%r9),%r14
  movzbl (%r9),%eax
  movzbl %al,%r8d
  mov    %r8d,%ecx
  sar    $0x4,%ecx
  cmp    $0xef,%r8d
  jle    L872
  mov    %eax,%ecx
  and    $0xf,%ecx
  mov    %eax,%r8d
  and    $0xf,%r8d
  cmp    $0x8,%r8d
  jg     L666
  movzbl 0x1(%r9),%ebx
  lea    0x3(%r9),%r14
  movzbl 0x2(%r9),%eax
  shl    $0x8,%eax
  or     %ebx,%eax
  cmp    $0xa,%cl
  ja     L1039
  movzbl %cl,%ecx
  lea    D14(%rip),%r9
  movslq (%r9,%rcx,4),%rcx
  add    %r9,%rcx
  notrack jmp *%rcx
L872:
  cmp    $0xb,%ecx
  jg     L453
  sar    $0x5,%r8d
  and    $0x1f,%eax
  mov    $0x20,%r15d
  jmp    L636
L453:
  lea    -0x6(%rcx),%r8d
  and    $0xf,%eax
  mov    $0x10,%r15d
L636:
  lea    0x6(%r8),%ecx
  mov    $0x2100,%ebx
  shr    %cl,%rbx
  and    $0x1,%ebx
  test   %eax,%eax
  je     L1009
  lea    0x0(,%rax,8),%ecx
  test   %rbx,%rbx
  cmovne %ecx,%eax
L690:
  cmp    $0xa,%r8d
  ja     L637
  mov    %r8d,%ecx
  lea    D12(%rip),%r9
  movslq (%r9,%rcx,4),%rcx
  add    %r9,%rcx
  notrack jmp *%rcx
L666:
  cmp    $0xb,%r8d
  mov    $0x8,%eax
  mov    $0x1,%ebx
  cmovge %ebx,%eax
  cmp    $0xa,%cl
  ja     L874
  movzbl %cl,%ecx
  lea    D29(%rip),%r9
  movslq (%r9,%rcx,4),%rcx
  add    %r9,%rcx
  notrack jmp *%rcx
L1009:
  test   %rbx,%rbx
  je     L772
  lea    0x2(%r9),%r14
  movzbl 0x1(%r9),%eax
  add    $0x1,%eax
  jmp    L690
L772:
  lea    0x2(%r9),%r14
  movzbl 0x1(%r9),%eax
  add    %r15d,%eax
  jmp    L690
  mov    %r14,%r9
  jmp    L515
  mov    %r14,%r9
L515:
  test   %ebp,%ebp
  je     L311
  movl   $0x0,-0x34(%rsp)
  mov    $0x0,%ebp
  jmp    L344
  mov    %r14,%r9
  jmp    L515
L311:
  cmp    %edx,%esi
  jne    L694
  mov    %ebp,-0x34(%rsp)
  test   %r10,%r10
  je     L344
L694:
  mov    %ebp,-0x34(%rsp)
  movl   $0x1,-0x1c(%rsp)
  jmp    L344
  mov    %r8d,%ebp
  jmp    L534
  mov    %r8d,%ebp
L534:
  lea    0x1(%r14),%rcx
  movzbl (%r14),%ebx
  mov    %bl,-0x25(%rsp)
L22:
  lea    0x1(%rcx),%r9
  movzbl (%rcx),%r13d
  movl   $0x0,-0x34(%rsp)
L344:
  test   %eax,%eax
  jle    L766
L703:
  mov    $0x0,%r8d
  mov    %ebp,%ebx
  mov    -0x34(%rsp),%ecx
  mov    %ecx,-0x24(%rsp)
  mov    %ebp,-0x14(%rsp)
  jmp    L171
  mov    %r8d,%ebp
  jmp    L534
  mov    %r8d,%ebp
  mov    %r14,%rcx
  jmp    L22
  mov    %r8d,%ebp
  mov    %r14,%rcx
  jmp    L22
  mov    %r8d,%ebp
  mov    %r14,%rcx
  jmp    L22
  lea    0x1(%r14),%r9
  movzbl (%r14),%r12d
  lea    -0x5(%r8),%ebp
  movl   $0x0,-0x34(%rsp)
  jmp    L344
  mov    %r14,%r9
  jmp    L99
  mov    %r14,%r9
L99:
  movl   $0x3,-0x34(%rsp)
  mov    $0x2,%ebp
  movl   $0x3,-0x20(%rsp)
  jmp    L344
  mov    %r14,%r9
  jmp    L99
  mov    %r14,%r9
  jmp    L673
  mov    %r14,%r9
L673:
  movl   $0x5,-0x34(%rsp)
  mov    $0x2,%ebp
  movl   $0x5,-0x20(%rsp)
  jmp    L344
  mov    %r14,%r9
  jmp    L673
L1039:
  mov    %r8d,%ebp
  mov    %r14,%r9
  movl   $0x0,-0x34(%rsp)
  jmp    L344
L637:
  mov    %r8d,%ebp
  mov    %r14,%r9
  movl   $0x0,-0x34(%rsp)
  jmp    L703
L874:
  mov    %r8d,%ebp
  mov    %r14,%r9
  movl   $0x0,-0x34(%rsp)
  jmp    L703
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
L354:
  movb   $0x0,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L354
  jmp    L93
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
L233:
  movb   $0xff,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L233
  jmp    L93
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
  mov    %r10,-0x10(%rsp)
  mov    -0x18(%rsp),%r10d
  jmp    L870
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
L595:
  add    $0x1,%r9
  movzbl -0x1(%r9),%edx
  mov    %dl,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L595
  jmp    L93
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
L565:
  mov    %r13b,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L565
L93:
  test   %eax,%eax
  jle    L766
L171:
  cmp    %edx,%esi
  jg     L868
  test   %r11d,%r11d
  jle    L201
  sub    $0x1,%r11d
  mov    %esi,%edx
  imul   %r11d,%edx
  movslq %edx,%rdx
  mov    %rdi,%r10
  mov    -0x30(%rsp),%rdi
  lea    (%rdi,%rdx,1),%rdi
  mov    $0x0,%edx
L868:
  cmp    $0xe,%ebp
  ja     L954
  lea    D3(%rip),%r15
  movslq (%r15,%rbx,4),%rcx
  add    %r15,%rcx
  notrack jmp *%rcx
  cmpl   $0x0,-0x1c(%rsp)
  je     L568
  test   %r10,%r10
  je     L800
  movslq %edx,%rcx
  mov    %r12d,%r14d
  xor    (%r10,%rcx,1),%r14b
  mov    %r14b,(%rdi,%rcx,1)
L94:
  sub    $0x1,%eax
  add    $0x1,%edx
L568:
  test   %r10,%r10
  je     L262
  test   %eax,%eax
  jle    L141
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L141
L561:
  movzbl -0x1(%r10,%rcx,1),%edx
  mov    %dl,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L561
  mov    -0x14(%rsp),%ecx
  mov    %ecx,-0x1c(%rsp)
  jmp    L93
L800:
  movslq %edx,%rcx
  mov    %r12b,(%rdi,%rcx,1)
  jmp    L94
L141:
  mov    -0x14(%rsp),%ecx
  mov    %ecx,-0x1c(%rsp)
  jmp    L93
L262:
  test   %eax,%eax
  jle    L305
  cmp    %esi,%edx
  jge    L305
  add    $0x1,%edx
  movslq %edx,%rcx
L263:
  movb   $0x0,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L263
  mov    -0x14(%rsp),%ecx
  mov    %ecx,-0x1c(%rsp)
  jmp    L93
  test   %r10,%r10
  je     L899
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
L635:
  mov    %r12d,%edx
  xor    -0x1(%r10,%rcx,1),%dl
  mov    %dl,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L635
  jmp    L93
L899:
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  jge    L93
  add    $0x1,%edx
  movslq %edx,%rcx
L473:
  mov    %r12b,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  jne    L473
  jmp    L93
  test   %r10,%r10
  je     L586
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  setl   %r14b
  lea    0x1(%rdx),%ecx
  movslq %ecx,%rcx
  test   %r14b,%r14b
  je     L93
  mov    -0x20(%rsp),%r15d
  mov    %r13b,-0x10(%rsp)
  jmp    L31
L586:
  test   %eax,%eax
  jle    L93
  cmp    %esi,%edx
  jge    L93
  add    $0x1,%edx
  movslq %edx,%rcx
  mov    -0x20(%rsp),%r15d
  mov    %r10,-0x10(%rsp)
  jmp    L525
L420:
  mov    -0x24(%rsp),%r15d
  mov    $0x1,%r8d
L493:
  test   %r15d,%r8d
  mov    $0x0,%edx
  cmovne %r12d,%edx
  mov    %dl,-0x1(%rdi,%rcx,1)
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r14b
  cmp    %ecx,%esi
  setg   %r10b
  add    $0x1,%rcx
  test   %r10b,%r14b
  je     L662
L525:
  add    %r8d,%r8d
  test   %r8b,%r8b
  jne    L493
  cmpl   $0x0,-0x34(%rsp)
  jne    L420
  movzbl (%r9),%r15d
  lea    0x1(%r9),%r9
  mov    $0x1,%r8d
  jmp    L493
L662:
  mov    %r15d,-0x20(%rsp)
  mov    -0x10(%rsp),%r10
  jmp    L93
L407:
  mov    -0x24(%rsp),%r15d
  mov    $0x1,%r8d
L1066:
  test   %r15d,%r8d
  je     L106
  mov    %r12d,%edx
  xor    -0x1(%r10,%rcx,1),%dl
  mov    %dl,-0x1(%rdi,%rcx,1)
L590:
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r14b
  cmp    %ecx,%esi
  setg   %r13b
  add    $0x1,%rcx
  test   %r13b,%r14b
  je     L179
L31:
  add    %r8d,%r8d
  test   %r8b,%r8b
  jne    L1066
  cmpl   $0x0,-0x34(%rsp)
  jne    L407
  movzbl (%r9),%r15d
  lea    0x1(%r9),%r9
  mov    $0x1,%r8d
  jmp    L1066
L106:
  movzbl -0x1(%r10,%rcx,1),%edx
  mov    %dl,-0x1(%rdi,%rcx,1)
  jmp    L590
L179:
  mov    %r15d,-0x20(%rsp)
  movzbl -0x10(%rsp),%r13d
  jmp    L93
L83:
  movzbl -0x25(%rsp),%edx
  mov    %dl,-0x1(%rdi,%rcx,1)
  add    $0x1,%eax
  mov    $0x1,%r10d
L911:
  sub    $0x1,%eax
  mov    %ecx,%edx
  test   %eax,%eax
  setg   %r15b
  cmp    %ecx,%esi
  setg   %r14b
  add    $0x1,%rcx
  test   %r14b,%r15b
  je     L156
L870:
  test   %r10d,%r10d
  je     L83
  mov    %r13b,-0x1(%rdi,%rcx,1)
  mov    $0x0,%r10d
  jmp    L911
L156:
  mov    %r10d,-0x18(%rsp)
  mov    -0x10(%rsp),%r10
  jmp    L93
L305:
  mov    -0x14(%rsp),%ecx
  mov    %ecx,-0x1c(%rsp)
  jmp    L93
L766:
  cmp    %r9,-0x8(%rsp)
  ja     L336
  mov    $0x1,%eax
  jmp    L268
L879:
  mov    $0x1,%eax
  jmp    L268
L201:
  mov    $0x0,%eax
  jmp    L268
L954:
  mov    $0x0,%eax
L268:
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
int bitmap_decompress1(char *output, int width, int height, char *input, int size) {
  char *prevline;
  char *line;
  char *end;
  char color1;
  char color2;
  char mix;
  int code;
  int mixmask;
  int mask;
  int opcode;
  int count;
  int offset;
  int isfillormix;
  int x;
  int lastopcode;
  int insertmix;
  int bicolor;
  int fom_mask;
  end = input + size;
  prevline = 0;
  line = 0;
  x = width;
  lastopcode = -1;
  insertmix = 0;
  bicolor = 0;
  color1 = 0;
  color2 = 0;
  mix = 0xff;
  mask = 0;
  fom_mask = 0;
  while (input < end) {
    fom_mask = 0;
    code = ((unsigned char)(*(input++)));
    opcode = code >> 4;
    switch (opcode) {
    case 0xc:
    case 0xd:
    case 0xe:
      opcode -= 6;
      count = code & 0xf;
      offset = 16;
      break;
    case 0xf:
      opcode = code & 0xf;
      if (opcode < 9) {
        count = ((unsigned char)(*(input++)));
        count |= ((unsigned char)(*(input++))) << 8;
      } else {
        count = (opcode < 0xb) ? 8 : 1;
      }
      offset = 0;
      break;
    default:
      opcode >>= 1;
      count = code & 0x1f;
      offset = 32;
      break;
    }
    if (offset != 0) {
      isfillormix = ((opcode == 2) || (opcode == 7));
      if (count == 0) {
        if (isfillormix) {
          count = ((unsigned char)(*(input++))) + 1;
        } else {
          count = ((unsigned char)(*(input++))) + offset;
        }
      } else if (isfillormix) {
        count <<= 3;
      }
    }
    switch (opcode) {
    case 0:
      if ((lastopcode == opcode) && !((x == width) && (prevline == 0))) {
        insertmix = 1;
      }
      break;
    case 8:
      color1 = ((unsigned char)(*(input++)));
    case 3:
      color2 = ((unsigned char)(*(input++)));
      break;
    case 6:
    case 7:
      mix = ((unsigned char)(*(input++)));
      opcode -= 5;
      break;
    case 9:
      mask = 0x03;
      opcode = 0x02;
      fom_mask = 3;
      break;
    case 0x0a:
      mask = 0x05;
      opcode = 0x02;
      fom_mask = 5;
      break;
    }
    lastopcode = opcode;
    mixmask = 0;
    while (count > 0) {
      if (x >= width) {
        if (height <= 0) {
          return 0;
        }
        x = 0;
        height--;
        prevline = line;
        line = output + height * width;
      }
      switch (opcode) {
      case 0:
        if (insertmix) {
          if (prevline == 0) {
            line[x] = mix;
          } else {
            line[x] = prevline[x] ^ mix;
          }
          insertmix = 0;
          count--;
          x++;
        }
        if (prevline == 0) {
          {
            while ((count > 0) && (x < width)) {
              line[x] = 0;
              count--;
              x++;
            }
          }
        } else {
          {
            while ((count > 0) && (x < width)) {
              line[x] = prevline[x];
              count--;
              x++;
            }
          }
        }
        break;
      case 1:
        if (prevline == 0) {
          {
            while ((count > 0) && (x < width)) {
              line[x] = mix;
              count--;
              x++;
            }
          }
        } else {
          {
            while ((count > 0) && (x < width)) {
              line[x] = prevline[x] ^ mix;
              count--;
              x++;
            }
          }
        }
        break;
      case 2:
        if (prevline == 0) {
          {
            while ((count > 0) && (x < width)) {
              {
                mixmask <<= 1;
                if ((mixmask & 0xff) == 0) {
                  mask = fom_mask ? fom_mask : ((unsigned char)(*(input++)));
                  mixmask = 1;
                }
              };
              if (mask & mixmask) {
                line[x] = mix;
              } else {
                line[x] = 0;
              };
              count--;
              x++;
            }
          }
        } else {
          {
            while ((count > 0) && (x < width)) {
              {
                mixmask <<= 1;
                if ((mixmask & 0xff) == 0) {
                  mask = fom_mask ? fom_mask : ((unsigned char)(*(input++)));
                  mixmask = 1;
                }
              };
              if (mask & mixmask) {
                line[x] = prevline[x] ^ mix;
              } else {
                line[x] = prevline[x];
              };
              count--;
              x++;
            }
          }
        }
        break;
      case 3: {
        while ((count > 0) && (x < width)) {
          line[x] = color2;
          count--;
          x++;
        }
      } break;
      case 4: {
        while ((count > 0) && (x < width)) {
          line[x] = ((unsigned char)(*(input++)));
          count--;
          x++;
        }
      } break;
      case 8: {
        while ((count > 0) && (x < width)) {
          if (bicolor) {
            line[x] = color2;
            bicolor = 0;
          } else {
            line[x] = color1;
            bicolor = 1;
            count++;
          };
          count--;
          x++;
        }
      } break;
      case 0xd: {
        while ((count > 0) && (x < width)) {
          line[x] = 0xff;
          count--;
          x++;
        }
      } break;
      case 0xe: {
        while ((count > 0) && (x < width)) {
          line[x] = 0;
          count--;
          x++;
        }
      } break;
      default:
        return 0;
        break;
      }
    }
  }
  return 1;
}
```