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

```asm
<rle_read>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %esi,-0x2c(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %ecx,-0x30(%rbp)
  mov    %r8d,-0x3c(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpl   $0x4,-0x3c(%rbp)
  jne    L92
  mov    -0x30(%rbp),%ecx
  mov    -0x38(%rbp),%rdx
  mov    -0x2c(%rbp),%esi
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <rle_read_32@plt>
  jmp    L156
L92:
  cmpl   $0x4,-0x3c(%rbp)
  setle  %al
  movzbl %al,%eax
  mov    %eax,%edi
  mov    $0x0,%eax
  call   <assert@plt>
  jmp    L124
L38:
  cmpl   $0x0,-0x2c(%rbp)
  jg     L68
  mov    $0xffffffff,%eax
  jmp    L156
L68:
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x11(%rbp)
  subl   $0x1,-0x2c(%rbp)
  movzbl -0x11(%rbp),%eax
  test   %al,%al
  jns    L175
  andb   $0x7f,-0x11(%rbp)
  movzbl -0x11(%rbp),%eax
  add    $0x1,%eax
  mov    %al,-0x11(%rbp)
  mov    -0x2c(%rbp),%eax
  cmp    -0x3c(%rbp),%eax
  jge    L40
  mov    $0xffffffff,%eax
  jmp    L156
L40:
  mov    -0x3c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rcx
  lea    -0xc(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x3c(%rbp),%eax
  cltq
  add    %rax,-0x28(%rbp)
  mov    -0x3c(%rbp),%eax
  sub    %eax,-0x2c(%rbp)
  jmp    L100
L154:
  mov    -0x30(%rbp),%eax
  cmp    -0x3c(%rbp),%eax
  jge    L50
  mov    $0xffffffff,%eax
  jmp    L156
L50:
  mov    -0x3c(%rbp),%eax
  movslq %eax,%rdx
  lea    -0xc(%rbp),%rcx
  mov    -0x38(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x3c(%rbp),%eax
  cltq
  add    %rax,-0x38(%rbp)
  mov    -0x3c(%rbp),%eax
  sub    %eax,-0x30(%rbp)
L100:
  movzbl -0x11(%rbp),%eax
  lea    -0x1(%rax),%edx
  mov    %dl,-0x11(%rbp)
  test   %al,%al
  jne    L154
  jmp    L124
L175:
  movzbl -0x11(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    -0x3c(%rbp),%eax
  imul   %edx,%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x30(%rbp),%eax
  cmp    -0x10(%rbp),%eax
  jl     L73
  mov    -0x2c(%rbp),%eax
  cmp    -0x10(%rbp),%eax
  jge    L48
L73:
  mov    $0xffffffff,%eax
  jmp    L156
L48:
  mov    -0x10(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rcx
  mov    -0x38(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x10(%rbp),%eax
  cltq
  add    %rax,-0x38(%rbp)
  mov    -0x10(%rbp),%eax
  sub    %eax,-0x30(%rbp)
  mov    -0x10(%rbp),%eax
  cltq
  add    %rax,-0x28(%rbp)
  mov    -0x10(%rbp),%eax
  sub    %eax,-0x2c(%rbp)
L124:
  cmpl   $0x0,-0x30(%rbp)
  jg     L38
  mov    $0x0,%eax
L156:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L49
  call   <__stack_chk_fail@plt>
L49:
  leave
  ret
```

assistant: ```c
int rle_read(unsigned char *in, int in_size, unsigned char *out, int out_size, int bytes_per_pixel) {
  unsigned char len;
  if (bytes_per_pixel == 4)
    return rle_read_32(in, in_size, out, out_size);
  assert(bytes_per_pixel <= 4);
  while (out_size > 0) {
    if (in_size < 1)
      return -1;
    len = *(in++);
    --in_size;
    if (len & 0x80) {
      char buffer[4];
      len &= 0x7f;
      len++;
      if (in_size < bytes_per_pixel)
        return -1;
      memcpy(buffer, in, bytes_per_pixel);
      in += bytes_per_pixel;
      in_size -= bytes_per_pixel;
      while (len--) {
        if (out_size < bytes_per_pixel)
          return -1;
        memcpy(out, buffer, bytes_per_pixel);
        out += bytes_per_pixel;
        out_size -= bytes_per_pixel;
      }
    } else {
      int i = bytes_per_pixel * (len + 1);
      if (out_size < i || in_size < i)
        return -1;
      memcpy(out, in, i);
      out += i;
      out_size -= i;
      in += i;
      in_size -= i;
    }
  }
  return 0;
}
```