user: What would the C source look like for the assembly code provided here:

```asm
<draw_block4x4_rgb8_etc2_planar_mode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x58,%rsp
  mov    %rdi,-0x58(%rbp)
  mov    %rsi,-0x60(%rbp)
  mov    -0x58(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  sar    %eax
  and    $0x3f,%eax
  mov    %eax,-0x40(%rbp)
  mov    -0x58(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0x40,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  sar    %eax
  and    $0x3f,%eax
  or     %edx,%eax
  mov    %eax,-0x3c(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x5,%eax
  and    $0x20,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x18,%eax
  or     %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    %eax,%eax
  and    $0x6,%eax
  or     %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  shr    $0x7,%al
  movzbl %al,%eax
  or     %edx,%eax
  mov    %eax,-0x38(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  sar    %eax
  and    $0x3e,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x1,%eax
  or     %edx,%eax
  mov    %eax,-0x34(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x4,%rax
  movzbl (%rax),%eax
  shr    %al
  movzbl %al,%eax
  mov    %eax,-0x30(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x4,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x5,%eax
  and    $0x20,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x5,%rax
  movzbl (%rax),%eax
  shr    $0x3,%al
  movzbl %al,%eax
  or     %edx,%eax
  mov    %eax,-0x2c(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x5,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x3,%eax
  and    $0x38,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x6,%rax
  movzbl (%rax),%eax
  shr    $0x5,%al
  movzbl %al,%eax
  or     %edx,%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x6,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x2,%eax
  and    $0x7c,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  add    $0x7,%rax
  movzbl (%rax),%eax
  shr    $0x6,%al
  movzbl %al,%eax
  or     %edx,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x58(%rbp),%rax
  add    $0x7,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  mov    %eax,-0x20(%rbp)
  mov    -0x40(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x40(%rbp),%eax
  sar    $0x4,%eax
  and    $0x3,%eax
  or     %edx,%eax
  mov    %eax,-0x40(%rbp)
  mov    -0x3c(%rbp),%eax
  lea    (%rax,%rax,1),%edx
  mov    -0x3c(%rbp),%eax
  sar    $0x6,%eax
  and    $0x1,%eax
  or     %edx,%eax
  mov    %eax,-0x3c(%rbp)
  mov    -0x38(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x38(%rbp),%eax
  sar    $0x4,%eax
  and    $0x3,%eax
  or     %edx,%eax
  mov    %eax,-0x38(%rbp)
  mov    -0x34(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x34(%rbp),%eax
  sar    $0x4,%eax
  and    $0x3,%eax
  or     %edx,%eax
  mov    %eax,-0x34(%rbp)
  mov    -0x30(%rbp),%eax
  lea    (%rax,%rax,1),%edx
  mov    -0x30(%rbp),%eax
  sar    $0x6,%eax
  and    $0x1,%eax
  or     %edx,%eax
  mov    %eax,-0x30(%rbp)
  mov    -0x2c(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x2c(%rbp),%eax
  sar    $0x4,%eax
  and    $0x3,%eax
  or     %edx,%eax
  mov    %eax,-0x2c(%rbp)
  mov    -0x28(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x28(%rbp),%eax
  sar    $0x4,%eax
  and    $0x3,%eax
  or     %edx,%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x24(%rbp),%eax
  lea    (%rax,%rax,1),%edx
  mov    -0x24(%rbp),%eax
  sar    $0x6,%eax
  and    $0x1,%eax
  or     %edx,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x20(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x20(%rbp),%eax
  sar    $0x4,%eax
  and    $0x3,%eax
  or     %edx,%eax
  mov    %eax,-0x20(%rbp)
  movl   $0x0,-0x48(%rbp)
  jmp    L29
L32:
  movl   $0x0,-0x44(%rbp)
  jmp    L3
L1:
  mov    -0x34(%rbp),%eax
  sub    -0x40(%rbp),%eax
  imul   -0x44(%rbp),%eax
  mov    %eax,%edx
  mov    -0x28(%rbp),%eax
  sub    -0x40(%rbp),%eax
  imul   -0x48(%rbp),%eax
  add    %eax,%edx
  mov    -0x40(%rbp),%eax
  shl    $0x2,%eax
  add    %edx,%eax
  add    $0x2,%eax
  sar    $0x2,%eax
  mov    %eax,%edi
  call   <clamp@plt>
  mov    %eax,-0x1c(%rbp)
  mov    -0x30(%rbp),%eax
  sub    -0x3c(%rbp),%eax
  imul   -0x44(%rbp),%eax
  mov    %eax,%edx
  mov    -0x24(%rbp),%eax
  sub    -0x3c(%rbp),%eax
  imul   -0x48(%rbp),%eax
  add    %eax,%edx
  mov    -0x3c(%rbp),%eax
  shl    $0x2,%eax
  add    %edx,%eax
  add    $0x2,%eax
  sar    $0x2,%eax
  mov    %eax,%edi
  call   <clamp@plt>
  mov    %eax,-0x18(%rbp)
  mov    -0x2c(%rbp),%eax
  sub    -0x38(%rbp),%eax
  imul   -0x44(%rbp),%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%eax
  sub    -0x38(%rbp),%eax
  imul   -0x48(%rbp),%eax
  add    %eax,%edx
  mov    -0x38(%rbp),%eax
  shl    $0x2,%eax
  add    %edx,%eax
  add    $0x2,%eax
  sar    $0x2,%eax
  mov    %eax,%edi
  call   <clamp@plt>
  mov    %eax,-0x14(%rbp)
  mov    -0x48(%rbp),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x44(%rbp),%eax
  add    %edx,%eax
  cltq
  lea    0x0(,%rax,4),%rdx
  mov    -0x60(%rbp),%rax
  lea    (%rdx,%rax,1),%rbx
  mov    -0x14(%rbp),%edx
  mov    -0x18(%rbp),%ecx
  mov    -0x1c(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <pack_rgb_alpha_0xff@plt>
  mov    %eax,(%rbx)
  addl   $0x1,-0x44(%rbp)
L3:
  cmpl   $0x3,-0x44(%rbp)
  jle    L1
  addl   $0x1,-0x48(%rbp)
L29:
  cmpl   $0x3,-0x48(%rbp)
  jle    L32
  nop
  nop
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
void draw_block4x4_rgb8_etc2_planar_mode(const unsigned char *bitstring, unsigned int *image_buffer) {
  int RO = (bitstring[0] & 0x7E) >> 1;
  int GO = ((bitstring[0] & 0x1) << 6) | ((bitstring[1] & 0x7E) >> 1);
  int BO = ((bitstring[1] & 0x1) << 5) | (bitstring[2] & 0x18) | ((bitstring[2] & 0x03) << 1) | ((bitstring[3] & 0x80) >> 7);
  int RH = ((bitstring[3] & 0x7C) >> 1) | (bitstring[3] & 0x1);
  int GH = (bitstring[4] & 0xFE) >> 1;
  int BH = ((bitstring[4] & 0x1) << 5) | ((bitstring[5] & 0xF8) >> 3);
  int RV = ((bitstring[5] & 0x7) << 3) | ((bitstring[6] & 0xE0) >> 5);
  int GV = ((bitstring[6] & 0x1F) << 2) | ((bitstring[7] & 0xC0) >> 6);
  int BV = bitstring[7] & 0x3F;
  RO = (RO << 2) | ((RO & 0x30) >> 4);
  GO = (GO << 1) | ((GO & 0x40) >> 6);
  BO = (BO << 2) | ((BO & 0x30) >> 4);
  RH = (RH << 2) | ((RH & 0x30) >> 4);
  GH = (GH << 1) | ((GH & 0x40) >> 6);
  BH = (BH << 2) | ((BH & 0x30) >> 4);
  RV = (RV << 2) | ((RV & 0x30) >> 4);
  GV = (GV << 1) | ((GV & 0x40) >> 6);
  BV = (BV << 2) | ((BV & 0x30) >> 4);
  for (int y = 0; y < 4; y++)
    for (int x = 0; x < 4; x++) {
      int r = clamp((x * (RH - RO) + y * (RV - RO) + 4 * RO + 2) >> 2);
      int g = clamp((x * (GH - GO) + y * (GV - GO) + 4 * GO + 2) >> 2);
      int b = clamp((x * (BH - BO) + y * (BV - BO) + 4 * BO + 2) >> 2);
      image_buffer[y * 4 + x] = pack_rgb_alpha_0xff(r, g, b);
    }
}
```