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

```asm
<rle_read>:
  endbr64
  push   %r15
  mov    %rdi,%r15
  push   %r14
  mov    %rdx,%r14
  push   %r13
  push   %r12
  mov    %ecx,%r12d
  push   %rbp
  mov    %esi,%ebp
  push   %rbx
  sub    $0x28,%rsp
  mov    %r8d,0x4(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  cmp    $0x4,%r8d
  je     L80
  setle  %dil
  xor    %eax,%eax
  movzbl %dil,%edi
  call   <assert@plt>
  movslq 0x4(%rsp),%r13
  test   %r12d,%r12d
  jg     L55
  jmp    L123
  nopw   0x0(%rax,%rax,1)
L159:
  add    $0x1,%ebx
  mov    %r12d,%eax
  movzbl %bl,%ebx
  imul   0x4(%rsp),%ebx
  cmp    %r12d,%ebp
  cmovle %ebp,%eax
  cmp    %ebx,%eax
  jl     L144
  movslq %ebx,%r15
  mov    0x8(%rsp),%rsi
  mov    %r14,%rdi
  sub    %ebx,%r12d
  mov    %r15,%rdx
  add    %r15,%r14
  sub    %ebx,%ebp
  call   <memcpy@plt>
  add    0x8(%rsp),%r15
L133:
  test   %r12d,%r12d
  jle    L123
L55:
  test   %ebp,%ebp
  jle    L144
  movzbl (%r15),%ebx
  lea    0x1(%r15),%rax
  sub    $0x1,%ebp
  mov    %rax,0x8(%rsp)
  test   %bl,%bl
  jns    L159
  and    $0x7f,%ebx
  cmp    %ebp,0x4(%rsp)
  jg     L144
  lea    0x14(%rsp),%r15
  mov    %r13,%rdx
  mov    %rax,%rsi
  mov    %r15,%rdi
  call   <memcpy@plt>
  cmp    %r12d,0x4(%rsp)
  jle    L75
  jmp    L144
  nopw   0x0(%rax,%rax,1)
L86:
  cmp    %r12d,0x4(%rsp)
  jg     L144
L75:
  mov    %r14,%rdi
  mov    %r13,%rdx
  mov    %r15,%rsi
  sub    $0x1,%ebx
  call   <memcpy@plt>
  add    %r13,%r14
  sub    0x4(%rsp),%r12d
  cmp    $0xff,%bl
  jne    L86
  mov    0x8(%rsp),%r15
  sub    0x4(%rsp),%ebp
  add    %r13,%r15
  jmp    L133
  nopl   0x0(%rax,%rax,1)
L144:
  mov    $0xffffffff,%eax
L95:
  mov    0x18(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L129
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax)
L80:
  mov    0x18(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L129
  add    $0x28,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1080 <rle_read_32@plt>
  nopl   (%rax)
L123:
  xor    %eax,%eax
  jmp    L95
L129:
  call   <__stack_chk_fail@plt>
```

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