user: 请从给定的汇编指令推导出C源代码:

```asm
<yuv420_to_yuv420_crop>:
  endbr64
  push   %r15
  mov    %rsi,%r10
  mov    %ecx,%esi
  mov    %rdx,%r15
  push   %r14
  mov    %rdi,%r11
  mov    %r9d,%r14d
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %r8d,%ebx
  sub    $0x18,%rsp
  mov    0x60(%rsp),%eax
  mov    0x68(%rsp),%ebp
  mov    0x58(%rsp),%r12d
  mov    0x50(%rsp),%edx
  mov    %eax,%ecx
  mov    0x70(%rsp),%rdi
  mov    0x78(%rsp),%r9
  or     %ebp,%ecx
  mov    0x80(%rsp),%r8
  or     %r12d,%ecx
  or     %edx,%ecx
  je     L2
  mov    %eax,%ecx
  imul   %r14d,%ecx
  add    %edx,%ecx
  movslq %ecx,%rcx
  add    %rcx,%r11
  mov    %eax,%ecx
  shr    $0x1f,%ecx
  add    %eax,%ecx
  add    %ebp,%eax
  sar    %ecx
  sub    %eax,%ebx
  imul   %r14d,%ecx
  mov    %ecx,%r13d
  shr    $0x1f,%r13d
  add    %r13d,%ecx
  mov    %edx,%r13d
  shr    $0x1f,%r13d
  sar    %ecx
  add    %edx,%r13d
  add    %r12d,%edx
  sar    %r13d
  sub    %edx,%esi
  add    %r13d,%ecx
  movslq %ecx,%rcx
  add    %rcx,%r10
  add    %rcx,%r15
L2:
  mov    %esi,%r12d
  mov    %esi,%r13d
  mov    %esi,(%r9)
  mov    %r14d,%ecx
  shr    $0x1f,%r12d
  imul   %ebx,%r13d
  mov    %ebx,(%r8)
  mov    %ebx,%r9d
  add    %esi,%r12d
  mov    %esi,%r8d
  mov    %r11,%rdx
  mov    %r10,0x8(%rsp)
  sar    %r12d
  mov    %r12d,%eax
  movslq %r13d,%r13
  imul   %ebx,%eax
  add    %rdi,%r13
  mov    %eax,%ebp
  shr    $0x1f,%ebp
  add    %eax,%ebp
  call   <plane_copy@plt>
  mov    %ebx,%eax
  mov    %r14d,%ecx
  mov    0x8(%rsp),%rdx
  shr    $0x1f,%eax
  shr    $0x1f,%ecx
  mov    %r12d,%r8d
  mov    %r12d,%esi
  add    %eax,%ebx
  add    %ecx,%r14d
  sar    %ebp
  mov    %r13,%rdi
  sar    %ebx
  sar    %r14d
  movslq %ebp,%rbp
  mov    %ebx,%r9d
  mov    %r14d,%ecx
  add    %r13,%rbp
  call   <plane_copy@plt>
  add    $0x18,%rsp
  mov    %ebx,%r9d
  mov    %r12d,%r8d
  pop    %rbx
  mov    %r14d,%ecx
  mov    %r15,%rdx
  mov    %r12d,%esi
  mov    %rbp,%rdi
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1050 <plane_copy@plt>
```

assistant: ```c
void yuv420_to_yuv420_crop(unsigned char *pInpY, unsigned char *pInpCb, unsigned char *pInpCr, int picWidth, int picHeight, int stride, int CropLeft, int CropRight, int CropTop, int CropBottom, unsigned char *pDest, int *pDestWidth, int *pDestHeight) {
  unsigned char *p_sour[3];
  unsigned char *p_dest[3];
  int inp_width = picWidth;
  int inp_height = picHeight;
  int out_width = picWidth;
  int out_height = picHeight;
  p_sour[0] = pInpY;
  p_sour[1] = pInpCb;
  p_sour[2] = pInpCr;
  if (CropLeft || CropRight || CropTop || CropBottom) {
    p_sour[0] = pInpY + (CropTop * stride + CropLeft);
    p_sour[1] = pInpCb + (CropTop / 2 * stride / 2 + CropLeft / 2);
    p_sour[2] = pInpCr + (CropTop / 2 * stride / 2 + CropLeft / 2);
    inp_width = inp_width - (CropLeft + CropRight);
    inp_height = inp_height - (CropTop + CropBottom);
    out_width = inp_width;
    out_height = inp_height;
  }
  *pDestWidth = out_width;
  *pDestHeight = out_height;
  p_dest[0] = pDest;
  p_dest[1] = p_dest[0] + out_width * out_height;
  p_dest[2] = p_dest[1] + out_width / 2 * out_height / 2;
  plane_copy(p_dest[0], out_width, p_sour[0], stride, inp_width, inp_height);
  plane_copy(p_dest[1], out_width / 2, p_sour[1], stride / 2, inp_width / 2, inp_height / 2);
  plane_copy(p_dest[2], out_width / 2, p_sour[2], stride / 2, inp_width / 2, inp_height / 2);
}
```