user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<CompressSparse>:
  endbr64
  push   %r15
  movslq %ecx,%r8
  lea    0x4(%rdx),%rax
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  lea    (%rdx,%r8,1),%rbp
  push   %rbx
  sub    $0x28,%rsp
  movslq (%rsi),%r15
  mov    %rdi,0x10(%rsp)
  mov    %rsi,0x18(%rsp)
  cmp    %rax,%rbp
  jbe    L384
  lea    -0x3(%rbp),%rax
  bswap  %ecx
  mov    %ecx,(%rdi)
  mov    %rdx,%r13
  mov    %rax,0x8(%rsp)
  add    %rdi,%r15
  lea    0x4(%rdi),%r14
L380:
  cmp    0x8(%rsp),%r13
  jae    L196
  cmp    %rbp,%r13
  jb     L64
L351:
  cmp    0x8(%rsp),%r13
  jb     L351
L196:
  cmp    %rbp,%r13
  jae    L175
  mov    %r13,%rax
L246:
  add    $0x1,%rax
  cmpb   $0x0,-0x1(%rax)
  jne    L73
  cmp    %rax,%rbp
  jne    L246
  lea    0x1(%r14),%rax
  cmp    %r15,%rax
  jae    L384
  movb   $0x7f,(%r14)
  mov    %rax,%r14
L175:
  mov    0x18(%rsp),%rax
  sub    0x10(%rsp),%r14
  mov    %r14d,(%rax)
L384:
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L64:
  lea    0x1(%r13),%rax
  mov    %r13,%r9
  xor    %r12d,%r12d
  jmp    L366
  nopl   0x0(%rax)
L62:
  add    $0x1,%r12
  add    $0x1,%rax
  cmp    %rdx,%rbp
  jbe    L277
L366:
  cmpb   $0x0,-0x1(%rax)
  mov    %rax,%rdx
  je     L62
  cmp    $0x2,%r12
  ja     L277
  mov    %rax,%r9
  xor    %r12d,%r12d
  add    $0x1,%rax
  cmp    %rdx,%rbp
  ja     L366
L277:
  mov    %r9,%rbx
  sub    %r13,%rbx
  je     L25
  cmp    $0x81,%rbx
  jbe    L391
  lea    0x81(%r14),%r10
  cmp    %r10,%r15
  ja     L314
  jmp    L384
  nopw   0x0(%rax,%rax,1)
L310:
  lea    0x102(%r14),%rax
  mov    %r10,%r14
  cmp    %r15,%rax
  jae    L384
  mov    %rax,%r10
L314:
  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     L310
L338:
  lea    0x1(%rbx),%r14
  cmp    $0x81,%rbx
  je     L243
L398:
  add    %r10,%r14
  cmp    %r15,%r14
  jae    L384
  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>
L25:
  cmp    $0x85,%r12
  jbe    L59
  lea    0x1(%r14),%rax
  cmp    %rax,%r15
  jbe    L384
  mov    %r12,%rdx
  jmp    L0
  nopl   0x0(%rax,%rax,1)
L286:
  add    $0x1,%rax
  cmp    %rax,%r15
  je     L384
L0:
  sub    $0x82,%rdx
  mov    %r12,%rsi
  movb   $0x7f,-0x1(%rax)
  mov    %rax,%r14
  sub    %rdx,%rsi
  add    %r13,%rsi
  cmp    $0x85,%rdx
  ja     L286
  cmp    $0x82,%rdx
  jbe    L321
L146:
  lea    0x1(%r14),%rax
  cmp    %r15,%rax
  jae    L384
  movb   $0x0,(%r14)
  sub    $0x3,%rdx
  lea    0x3(%rsi),%r13
L296:
  lea    0x1(%rax),%r14
  cmp    %r15,%r14
  jae    L384
  lea    -0x3(%rdx),%ecx
  add    %rdx,%r13
  mov    %cl,(%rax)
  jmp    L380
L243:
  lea    0x2(%r10),%r14
  cmp    %r14,%r15
  jbe    L384
  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    L398
L391:
  mov    %r14,%r10
  jmp    L338
L73:
  mov    %rbp,%rdx
  sub    %r13,%rdx
  lea    0x1(%r14,%rdx,1),%r12
  cmp    %r15,%r12
  jae    L384
  movb   $0xff,(%r14)
  lea    0x1(%r14),%rdi
  mov    %r13,%rsi
  mov    %r12,%r14
  call   <memcpy@plt>
  jmp    L175
L59:
  cmp    $0x82,%r12
  jbe    L204
  mov    %r12,%rdx
  mov    %r13,%rsi
  jmp    L146
  cs nopw 0x0(%rax,%rax,1)
L204:
  cmp    $0x2,%r12
  jbe    L380
  mov    %r12,%rdx
  mov    %r14,%rax
  jmp    L296
L321:
  mov    %rsi,%r13
  jmp    L296
```

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