user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<bayer_unshuffle_preview>:
  endbr64
  push   %r15
  mov    %edx,%eax
  mov    $0x1,%r11d
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rcx,%rbx
  mov    %eax,%ecx
  sar    %cl,%esi
  shl    %cl,%r11d
  sub    $0x58,%rsp
  mov    %r8,0x10(%rsp)
  mov    %fs:0x28,%rdx
  mov    %rdx,0x48(%rsp)
  mov    %edi,%edx
  mov    %esi,0x24(%rsp)
  sar    %cl,%edx
  mov    %edx,(%rsp)
  test   %esi,%esi
  jle    L32
  lea    -0x1(%rax),%esi
  movl   $0x0,0x20(%rsp)
  mov    %edi,%r12d
  mov    %edi,%ebp
  mov    %esi,0xc(%rsp)
  add    %esi,%esi
  sar    %r12d
  mov    %esi,0x4(%rsp)
  lea    -0x1(%rax,%rax,1),%esi
  mov    %esi,0x8(%rsp)
  mov    %edi,%esi
  shl    %cl,%esi
  movslq %esi,%rax
  mov    %rax,0x18(%rsp)
  lea    -0x1(%rdx),%eax
  lea    0x3(%rax,%rax,2),%rax
  mov    %rax,0x28(%rsp)
L29:
  mov    (%rsp),%eax
  mov    0x10(%rsp),%r13
  xor    %r14d,%r14d
  test   %eax,%eax
  jle    L20
  nopl   0x0(%rax,%rax,1)
L45:
  movq   $0x0,0x3c(%rsp)
  movl   $0x0,0x44(%rsp)
  test   %r11d,%r11d
  jle    L44
  movzbl 0xc(%rsp),%ecx
  mov    %r14d,%r10d
  xor    %r15d,%r15d
  shl    %cl,%r10d
  xor    %ecx,%ecx
  nopw   0x0(%rax,%rax,1)
L49:
  mov    %r15d,%esi
  xor    %edx,%edx
  and    $0x1,%esi
  jmp    L19
  nopw   0x0(%rax,%rax,1)
L11:
  mov    %edx,%eax
  not    %eax
  and    $0x1,%eax
  add    %esi,%eax
  cltq
  mov    0x3c(%rsp,%rax,4),%ecx
L19:
  mov    %edx,%r8d
  mov    %edx,%eax
  and    $0x1,%r8d
  sar    %eax
  mov    %r8d,%edi
  add    %r10d,%eax
  xor    $0x1,%edi
  lea    (%rax,%r12,1),%r9d
  add    %esi,%edi
  test   %r8d,%r8d
  cmove  %r9d,%eax
  movslq %edi,%rdi
  add    $0x1,%edx
  cltq
  movzbl (%rbx,%rax,1),%eax
  add    %eax,%ecx
  mov    %ecx,0x3c(%rsp,%rdi,4)
  cmp    %edx,%r11d
  jne    L11
  add    $0x1,%r15d
  add    %ebp,%r10d
  cmp    %r15d,%r11d
  je     L75
  mov    %r15d,%eax
  and    $0x1,%eax
  mov    0x40(%rsp,%rax,4),%ecx
  jmp    L49
  nop
L75:
  mov    0x4(%rsp),%edi
  mov    0x3c(%rsp),%eax
  mov    %edi,%ecx
  sar    %cl,%eax
  movzbl 0x8(%rsp),%ecx
  mov    %eax,%esi
  mov    0x40(%rsp),%eax
  sar    %cl,%eax
  mov    %edi,%ecx
  mov    %eax,%edx
  mov    0x44(%rsp),%eax
  sar    %cl,%eax
L87:
  mov    %sil,0x0(%r13)
  add    $0x1,%r14d
  add    $0x3,%r13
  mov    %dl,-0x2(%r13)
  mov    %al,-0x1(%r13)
  cmp    %r14d,(%rsp)
  jne    L45
  mov    0x28(%rsp),%rsi
  add    %rsi,0x10(%rsp)
L20:
  addl   $0x1,0x20(%rsp)
  add    0x18(%rsp),%rbx
  mov    0x20(%rsp),%eax
  cmp    %eax,0x24(%rsp)
  jne    L29
L32:
  mov    0x48(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L67
  add    $0x58,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L44:
  xor    %eax,%eax
  xor    %edx,%edx
  xor    %esi,%esi
  jmp    L87
L67:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
void bayer_unshuffle_preview(int w, int h, int scale, unsigned char *raw, unsigned char *output) {
  int x, y, nx, ny;
  int colour;
  int rgb[3];
  int nw = w >> scale;
  int nh = h >> scale;
  int incr = 1 << scale;
  for (ny = 0; ny < nh; ++ny, raw += w << scale) {
    for (nx = 0; nx < nw; ++nx, output += 3) {
      rgb[0] = 0;
      rgb[1] = 0;
      rgb[2] = 0;
      for (y = 0; y < incr; ++y) {
        for (x = 0; x < incr; ++x) {
          colour = 1 - (x & 1) + (y & 1);
          rgb[colour] += raw[y * w + (nx << (scale - 1)) + (x >> 1) + ((x & 1) ? 0 : (w >> 1))];
        }
      }
      output[0] = rgb[0] >> (2 * scale - 2);
      output[1] = rgb[1] >> (2 * scale - 1);
      output[2] = rgb[2] >> (2 * scale - 2);
    }
  }
}
```