user: Converte this assembly snippet into its equivalent C code:

```asm
<CompressSparse>:
  endbr64
  push   %r15
  movslq %ecx,%r8
  lea    0x4(%rdx),%rax
  push   %r14
  push   %r13
  push   %r12
  lea    (%rdx,%r8,1),%r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  movslq (%rsi),%r15
  mov    %rdi,0x10(%rsp)
  mov    %rsi,0x18(%rsp)
  cmp    %rax,%r12
  jbe    L73
  lea    -0x3(%r12),%rax
  bswap  %ecx
  mov    %ecx,(%rdi)
  mov    %rdx,%r13
  mov    %rax,0x8(%rsp)
  add    %rdi,%r15
  lea    0x4(%rdi),%r14
L166:
  cmp    %r13,0x8(%rsp)
  jbe    L150
  cmp    %r12,%r13
  jae    L166
  lea    0x1(%r13),%rax
  mov    %r13,%r9
  xor    %ebp,%ebp
  jmp    L326
  cs nopw 0x0(%rax,%rax,1)
L255:
  add    $0x1,%rbp
  add    $0x1,%rax
  cmp    %rdx,%r12
  jbe    L249
L326:
  cmpb   $0x0,-0x1(%rax)
  mov    %rax,%rdx
  je     L255
  cmp    $0x2,%rbp
  ja     L249
  mov    %rax,%r9
  xor    %ebp,%ebp
  add    $0x1,%rax
  cmp    %rdx,%r12
  ja     L326
L249:
  mov    %r9,%rbx
  sub    %r13,%rbx
  je     L294
  cmp    $0x81,%rbx
  jbe    L179
  lea    0x81(%r14),%r10
  cmp    %r10,%r15
  ja     L197
  jmp    L73
  nopl   0x0(%rax)
L159:
  lea    0x102(%r14),%rax
  mov    %r10,%r14
  cmp    %r15,%rax
  jae    L73
  mov    %rax,%r10
L197:
  movb   $0xff,(%r14)
  mov    %r13,%rsi
  lea    0x1(%r14),%rdi
  mov    $0x80,%edx
  add    $0xffffffffffffff80,%rbx
  mov    %r10,(%rsp)
  sub    $0xffffffffffffff80,%r13
  call   <memcpy@plt>
  cmp    $0x81,%rbx
  mov    (%rsp),%r10
  ja     L159
L65:
  lea    0x1(%rbx),%r14
  cmp    $0x81,%rbx
  je     L246
L157:
  add    %r10,%r14
  cmp    %r15,%r14
  jae    L73
  lea    -0x1(%rbx),%eax
  mov    %r13,%rsi
  lea    0x1(%r10),%rdi
  mov    %rbx,%rdx
  or     $0xffffff80,%eax
  add    %rbx,%r13
  mov    %al,(%r10)
  call   <memcpy@plt>
L294:
  cmp    $0x85,%rbp
  jbe    L79
  lea    0x1(%r14),%rax
  cmp    %rax,%r15
  jbe    L73
  mov    %rbp,%rdx
  jmp    L289
  nopl   0x0(%rax,%rax,1)
L51:
  add    $0x1,%rax
  cmp    %r15,%rax
  je     L73
L289:
  sub    $0x82,%rdx
  mov    %rbp,%rsi
  movb   $0x7f,-0x1(%rax)
  mov    %rax,%r14
  sub    %rdx,%rsi
  add    %r13,%rsi
  cmp    $0x85,%rdx
  ja     L51
  cmp    $0x82,%rdx
  jbe    L323
L298:
  lea    0x1(%r14),%rax
  cmp    %r15,%rax
  jae    L73
  movb   $0x0,(%r14)
  sub    $0x3,%rdx
  lea    0x3(%rsi),%r13
L363:
  lea    0x1(%rax),%r14
  cmp    %r15,%r14
  jae    L73
  lea    -0x3(%rdx),%ecx
  add    %rdx,%r13
  mov    %cl,(%rax)
  jmp    L166
L150:
  cmp    %r12,%r13
  jae    L143
  mov    %r13,%rax
L109:
  add    $0x1,%rax
  cmpb   $0x0,-0x1(%rax)
  jne    L352
  cmp    %rax,%r12
  jne    L109
  lea    0x1(%r14),%rax
  cmp    %r15,%rax
  jae    L73
  movb   $0x7f,(%r14)
  mov    %rax,%r14
L143:
  mov    0x18(%rsp),%rax
  sub    0x10(%rsp),%r14
  mov    %r14d,(%rax)
L73:
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L246:
  lea    0x2(%r10),%r14
  cmp    %r14,%r15
  jbe    L73
  movb   $0x80,(%r10)
  lea    0x1(%r10),%rdi
  mov    %r13,%rsi
  mov    $0x1,%edx
  add    $0x1,%r13
  mov    $0x80,%ebx
  call   <memcpy@plt>
  mov    %r14,%r10
  mov    $0x81,%r14d
  jmp    L157
L179:
  mov    %r14,%r10
  jmp    L65
L352:
  mov    %r12,%rdx
  sub    %r13,%rdx
  lea    0x1(%r14,%rdx,1),%r12
  cmp    %r15,%r12
  jae    L73
  movb   $0xff,(%r14)
  lea    0x1(%r14),%rdi
  mov    %r13,%rsi
  mov    %r12,%r14
  call   <memcpy@plt>
  jmp    L143
L323:
  mov    %rsi,%r13
  jmp    L363
L79:
  cmp    $0x82,%rbp
  jbe    L284
  mov    %rbp,%rdx
  mov    %r13,%rsi
  jmp    L298
  xchg   %ax,%ax
L284:
  cmp    $0x2,%rbp
  jbe    L166
  mov    %rbp,%rdx
  mov    %r14,%rax
  jmp    L363
```

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);
}
```