user: What is the c source code of the assembly code below:

```asm
<CompressSparse>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,0x20(%rsp)
  mov    %rsi,0x28(%rsp)
  movslq %ecx,%r15
  add    %rdx,%r15
  lea    0x4(%rdx),%rax
  cmp    %rax,%r15
  jbe    L65
  mov    %rdx,%rbx
  movslq (%rsi),%r13
  add    %rdi,%r13
  mov    %ecx,%eax
  sar    $0x18,%eax
  mov    %al,(%rdi)
  mov    %ecx,%eax
  sar    $0x10,%eax
  mov    %al,0x1(%rdi)
  movzbl %ch,%eax
  mov    %al,0x2(%rdi)
  lea    0x4(%rdi),%rbp
  mov    %cl,0x3(%rdi)
  lea    -0x3(%r15),%rax
  mov    %rax,0x18(%rsp)
L129:
  cmp    0x18(%rsp),%rbx
  jae    L125
  mov    $0x0,%edx
  cmp    %r15,%rbx
  jb     L194
L346:
  cmp    $0x82,%rdx
  jbe    L262
  lea    0x1(%rbp),%rax
  cmp    %r13,%rax
  jae    L65
  movb   $0x0,0x0(%rbp)
  sub    $0x3,%rdx
  add    $0x3,%rbx
L355:
  lea    0x1(%rax),%rbp
  cmp    %r13,%rbp
  jae    L65
  lea    -0x3(%rdx),%ecx
  mov    %cl,(%rax)
  add    %rdx,%rbx
  jmp    L129
L194:
  lea    0x1(%rbx),%rax
  mov    %rbx,%r14
  mov    $0x0,%r12d
  jmp    L58
L176:
  cmp    $0x2,%r12
  ja     L296
  mov    %rax,%r14
  mov    $0x0,%r12d
L85:
  lea    0x1(%rax),%rdx
  cmp    %r15,%rax
  je     L296
  mov    %rdx,%rax
L58:
  cmpb   $0x0,-0x1(%rax)
  jne    L176
  add    $0x1,%r12
  jmp    L85
L296:
  sub    %rbx,%r14
  je     L9
  cmp    $0x81,%r14
  jbe    L223
  lea    0x81(%rbp),%rax
  cmp    %rax,%r13
  jbe    L65
L145:
  mov    %rbp,0x8(%rsp)
  movb   $0xff,0x0(%rbp)
  lea    0x1(%rbp),%rdi
  mov    $0x80,%edx
  mov    %rbx,%rsi
  call   <memcpy@plt>
  add    $0xffffffffffffff80,%r14
  mov    %rbp,%rax
  add    $0x81,%rbp
  mov    %rbx,0x10(%rsp)
  sub    $0xffffffffffffff80,%rbx
  cmp    $0x81,%r14
  jbe    L388
  mov    0x8(%rsp),%rax
  add    $0x102,%rax
  cmp    %rax,%r13
  ja     L145
  jmp    L65
L388:
  je     L373
  test   %r14,%r14
  jne    L265
  lea    0x83(%rax),%rsi
  mov    %rsi,0x8(%rsp)
  cmp    %r13,%rsi
  jae    L65
  movb   $0x80,0x81(%rax)
  lea    0x82(%rax),%rdi
  mov    $0x1,%edx
  mov    %rbx,%rsi
  call   <memcpy@plt>
  mov    0x10(%rsp),%rcx
  add    $0x81,%rcx
  jmp    L189
L9:
  mov    %rbx,%rcx
  mov    %rbp,0x8(%rsp)
  jmp    L189
L93:
  mov    %r12,%rdx
  mov    %rcx,%rbx
  mov    0x8(%rsp),%rbp
  jmp    L346
L262:
  cmp    $0x2,%rdx
  jbe    L129
  mov    %rbp,%rax
  jmp    L355
L125:
  cmp    %r15,%rbx
  jae    L49
  mov    %rbx,%rax
L51:
  add    $0x1,%rax
  cmpb   $0x0,-0x1(%rax)
  jne    L254
  cmp    %rax,%r15
  jne    L51
  lea    0x1(%rbp),%rax
  cmp    %r13,%rax
  jae    L65
  movb   $0x7f,0x0(%rbp)
  mov    %rax,%rbp
L49:
  sub    0x20(%rsp),%rbp
  mov    0x28(%rsp),%rax
  mov    %ebp,(%rax)
  jmp    L65
L254:
  mov    %r15,%rdx
  sub    %rbx,%rdx
  lea    0x1(%rbp,%rdx,1),%r12
  cmp    %r13,%r12
  jae    L65
  movb   $0xff,0x0(%rbp)
  lea    0x1(%rbp),%rdi
  mov    %rbx,%rsi
  call   <memcpy@plt>
  mov    %r12,%rbp
  jmp    L49
L223:
  jne    L265
L373:
  lea    0x2(%rbp),%rax
  cmp    %rax,%r13
  jbe    L65
  movb   $0x80,0x0(%rbp)
  lea    0x1(%rbp),%rdi
  mov    $0x1,%edx
  mov    %rbx,%rsi
  call   <memcpy@plt>
  add    $0x2,%rbp
  add    $0x1,%rbx
  mov    $0x80,%r14d
L265:
  lea    0x1(%rbp,%r14,1),%rax
  mov    %rax,0x8(%rsp)
  cmp    %r13,%rax
  jae    L65
  lea    -0x1(%r14),%eax
  or     $0xffffff80,%eax
  mov    %al,0x0(%rbp)
  lea    0x1(%rbp),%rdi
  mov    %r14,%rdx
  mov    %rbx,%rsi
  call   <memcpy@plt>
  lea    (%rbx,%r14,1),%rcx
L189:
  cmp    $0x85,%r12
  jbe    L93
  mov    0x8(%rsp),%rax
  add    $0x1,%rax
  cmp    %rax,%r13
  jbe    L65
  mov    %r12,%rdx
L244:
  mov    %rax,%rbp
  movb   $0x7f,-0x1(%rax)
  sub    $0x82,%rdx
  mov    %r12,%rbx
  sub    %rdx,%rbx
  add    %rcx,%rbx
  cmp    $0x85,%rdx
  jbe    L346
  add    $0x1,%rax
  cmp    %rax,%r13
  jne    L244
L65:
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
void CompressSparse(void *pvOutBuffer, int *pcbOutBuffer, void *pvInBuffer, int cbInBuffer) {
  unsigned char *pbOutBufferEnd = (unsigned char *)pvOutBuffer + *pcbOutBuffer;
  unsigned char *pbInBufferEnd = (unsigned char *)pvInBuffer + cbInBuffer;
  unsigned char *pbLastNonZero = (unsigned char *)pvInBuffer;
  unsigned char *pbOutBuffer0 = (unsigned char *)pvOutBuffer;
  unsigned char *pbInBuffPtr = (unsigned char *)pvInBuffer;
  unsigned char *pbOutBuffer = (unsigned char *)pvOutBuffer;
  unsigned char *pbInBuffer = (unsigned char *)pvInBuffer;
  size_t NumberOfNonZeros;
  size_t NumberOfZeros;
  if ((pbInBuffer + 4) >= pbInBufferEnd)
    return;
  *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x18);
  *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x10);
  *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x08);
  *pbOutBuffer++ = (unsigned char)(cbInBuffer >> 0x00);
  while (pbInBuffer < (pbInBufferEnd - 3)) {
    pbLastNonZero = pbInBuffer;
    pbInBuffPtr = pbInBuffer;
    NumberOfZeros = 0;
    if (pbInBuffPtr < pbInBufferEnd) {
      do {
        if (*pbInBuffPtr == 0) {
          NumberOfZeros++;
        } else {
          if (NumberOfZeros >= 3)
            break;
          pbLastNonZero = pbInBuffPtr + 1;
          NumberOfZeros = 0;
        }
      } while (++pbInBuffPtr < pbInBufferEnd);
    }
    NumberOfNonZeros = pbLastNonZero - pbInBuffer;
    if (NumberOfNonZeros != 0) {
      while (NumberOfNonZeros > 0x81) {
        if ((pbOutBuffer + 0x81) >= pbOutBufferEnd)
          return;
        *pbOutBuffer++ = 0xFF;
        memcpy(pbOutBuffer, pbInBuffer, 0x80);
        NumberOfNonZeros -= 0x80;
        pbOutBuffer += 0x80;
        pbInBuffer += 0x80;
      }
      if (NumberOfNonZeros > 0x80) {
        if ((pbOutBuffer + 2) >= pbOutBufferEnd)
          return;
        *pbOutBuffer++ = 0x80;
        memcpy(pbOutBuffer, pbInBuffer, 1);
        NumberOfNonZeros--;
        pbOutBuffer++;
        pbInBuffer++;
      }
      if (NumberOfNonZeros >= 0x01) {
        if ((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd)
          return;
        *pbOutBuffer++ = (unsigned char)(0x80 | (NumberOfNonZeros - 1));
        memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
        pbOutBuffer += NumberOfNonZeros;
        pbInBuffer += NumberOfNonZeros;
      } else {
        if ((pbOutBuffer + 2) >= pbOutBufferEnd)
          return;
        *pbOutBuffer++ = 0x80;
        memcpy(pbOutBuffer, pbInBuffer, 1);
        pbOutBuffer++;
        pbInBuffer++;
      }
    }
    while (NumberOfZeros > 0x85) {
      if ((pbOutBuffer + 1) >= pbOutBufferEnd)
        return;
      *pbOutBuffer++ = 0x7F;
      NumberOfZeros -= 0x82;
      pbInBuffer += 0x82;
    }
    if (NumberOfZeros > 0x82) {
      if ((pbOutBuffer + 1) >= pbOutBufferEnd)
        return;
      *pbOutBuffer++ = 0;
      NumberOfZeros -= 0x03;
      pbInBuffer += 0x03;
    }
    if (NumberOfZeros >= 3) {
      if ((pbOutBuffer + 1) >= pbOutBufferEnd)
        return;
      *pbOutBuffer++ = (unsigned char)(NumberOfZeros - 3);
      pbInBuffer += NumberOfZeros;
    }
  }
  if (pbInBuffer < pbInBufferEnd) {
    pbInBuffPtr = pbInBuffer;
    for (;;) {
      if (*pbInBuffPtr++ != 0) {
        NumberOfNonZeros = (pbInBufferEnd - pbInBuffer);
        if ((pbOutBuffer + NumberOfNonZeros + 1) >= pbOutBufferEnd)
          return;
        *pbOutBuffer++ = 0xFF;
        memcpy(pbOutBuffer, pbInBuffer, NumberOfNonZeros);
        pbOutBuffer += NumberOfNonZeros;
        break;
      } else {
        if (pbInBuffPtr < pbInBufferEnd)
          continue;
        if ((pbOutBuffer + 1) >= pbOutBufferEnd)
          return;
        *pbOutBuffer++ = 0x7F;
        break;
      }
    }
  }
  *pcbOutBuffer = (int)(pbOutBuffer - pbOutBuffer0);
}
```