user: Translate the below assembly code into C programming language:

```asm
<NV21Transform>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x70,%rsp
  mov    %rdi,-0x58(%rbp)
  mov    %rsi,-0x60(%rbp)
  mov    %edx,-0x64(%rbp)
  mov    %ecx,-0x68(%rbp)
  mov    %r8d,-0x6c(%rbp)
  mov    -0x60(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x58(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  movl   $0x0,-0x48(%rbp)
  movl   $0x0,-0x44(%rbp)
  movl   $0x0,-0x40(%rbp)
  mov    -0x6c(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  jne    L453
  mov    -0x6c(%rbp),%eax
  and    $0x40,%eax
  test   %eax,%eax
  je     L546
L453:
  movl   $0x0,-0x48(%rbp)
  jmp    L188
L546:
  movl   $0x1,-0x48(%rbp)
L188:
  mov    -0x6c(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  jne    L495
  mov    -0x6c(%rbp),%eax
  and    $0x20,%eax
  test   %eax,%eax
  je     L102
L495:
  mov    -0x6c(%rbp),%eax
  and    $0x1,%eax
  mov    %eax,-0x44(%rbp)
  mov    -0x6c(%rbp),%eax
  sar    %eax
  and    $0x1,%eax
  mov    %eax,-0x40(%rbp)
  jmp    L134
L102:
  mov    -0x6c(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  je     L190
  mov    -0x6c(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0x44(%rbp)
  movl   $0x0,-0x40(%rbp)
  jmp    L134
L190:
  mov    -0x6c(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0x44(%rbp)
  movl   $0x1,-0x40(%rbp)
L134:
  mov    -0x68(%rbp),%eax
  imul   -0x64(%rbp),%eax
  mov    %eax,-0x20(%rbp)
  mov    -0x20(%rbp),%edx
  mov    %edx,%eax
  add    %eax,%eax
  add    %edx,%eax
  mov    %eax,%edx
  shr    $0x1f,%edx
  add    %edx,%eax
  sar    %eax
  mov    %eax,-0x1c(%rbp)
  cmpl   $0x0,-0x48(%rbp)
  jne    L657
  cmpl   $0x0,-0x44(%rbp)
  jne    L657
  cmpl   $0x0,-0x40(%rbp)
  jne    L657
  mov    -0x1c(%rbp),%edx
  mov    -0x8(%rbp),%rcx
  mov    -0x10(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  jmp    L547
L657:
  mov    -0x68(%rbp),%eax
  sar    %eax
  mov    %eax,-0x18(%rbp)
  mov    -0x64(%rbp),%eax
  sar    %eax
  mov    %eax,-0x14(%rbp)
  cmpl   $0x1,-0x48(%rbp)
  jne    L391
  cmpl   $0x1,-0x44(%rbp)
  jne    L314
  cmpl   $0x1,-0x40(%rbp)
  jne    L658
  mov    -0x20(%rbp),%eax
  sub    -0x68(%rbp),%eax
  jmp    L392
L658:
  mov    -0x20(%rbp),%eax
  sub    $0x1,%eax
L392:
  mov    %eax,-0x3c(%rbp)
  cmpl   $0x1,-0x40(%rbp)
  jne    L298
  mov    $0x1,%eax
  jmp    L148
L298:
  mov    $0xffffffff,%eax
L148:
  mov    %eax,-0x38(%rbp)
  mov    -0x68(%rbp),%eax
  neg    %eax
  mov    %eax,-0x34(%rbp)
  jmp    L115
L314:
  cmpl   $0x1,-0x40(%rbp)
  je     L523
  mov    -0x68(%rbp),%eax
  sub    $0x1,%eax
  jmp    L72
L523:
  mov    $0x0,%eax
L72:
  mov    %eax,-0x3c(%rbp)
  cmpl   $0x1,-0x40(%rbp)
  jne    L403
  mov    $0x1,%eax
  jmp    L600
L403:
  mov    $0xffffffff,%eax
L600:
  mov    %eax,-0x38(%rbp)
  mov    -0x68(%rbp),%eax
  mov    %eax,-0x34(%rbp)
L115:
  movl   $0xffffffff,-0x28(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L522
L142:
  mov    -0x3c(%rbp),%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x30(%rbp)
  jmp    L16
L572:
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  mov    -0x34(%rbp),%eax
  add    %eax,-0x24(%rbp)
  addl   $0x1,-0x30(%rbp)
L16:
  mov    -0x30(%rbp),%eax
  cmp    -0x64(%rbp),%eax
  jl     L572
  mov    -0x38(%rbp),%eax
  add    %eax,-0x3c(%rbp)
  addl   $0x1,-0x2c(%rbp)
L522:
  mov    -0x2c(%rbp),%eax
  cmp    -0x68(%rbp),%eax
  jl     L142
  cmpl   $0x1,-0x44(%rbp)
  jne    L240
  cmpl   $0x1,-0x40(%rbp)
  jne    L291
  mov    -0x1c(%rbp),%eax
  sub    -0x68(%rbp),%eax
  jmp    L510
L291:
  mov    -0x1c(%rbp),%eax
  sub    $0x2,%eax
L510:
  mov    %eax,-0x3c(%rbp)
  cmpl   $0x1,-0x40(%rbp)
  jne    L531
  mov    $0x2,%eax
  jmp    L173
L531:
  mov    $0xfffffffe,%eax
L173:
  mov    %eax,-0x38(%rbp)
  mov    -0x68(%rbp),%eax
  neg    %eax
  mov    %eax,-0x34(%rbp)
  jmp    L75
L240:
  cmpl   $0x1,-0x40(%rbp)
  je     L349
  mov    -0x20(%rbp),%edx
  mov    -0x68(%rbp),%eax
  add    %edx,%eax
  sub    $0x2,%eax
  jmp    L409
L349:
  mov    -0x20(%rbp),%eax
L409:
  mov    %eax,-0x3c(%rbp)
  cmpl   $0x1,-0x40(%rbp)
  jne    L110
  mov    $0x2,%eax
  jmp    L94
L110:
  mov    $0xfffffffe,%eax
L94:
  mov    %eax,-0x38(%rbp)
  mov    -0x68(%rbp),%eax
  mov    %eax,-0x34(%rbp)
L75:
  mov    -0x20(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x28(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L129
L0:
  mov    -0x3c(%rbp),%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x30(%rbp)
  jmp    L212
L537:
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    -0x24(%rbp),%edx
  movslq %edx,%rdx
  lea    0x1(%rdx),%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  mov    -0x34(%rbp),%eax
  add    %eax,-0x24(%rbp)
  addl   $0x1,-0x30(%rbp)
L212:
  mov    -0x30(%rbp),%eax
  cmp    -0x14(%rbp),%eax
  jl     L537
  mov    -0x38(%rbp),%eax
  add    %eax,-0x3c(%rbp)
  addl   $0x1,-0x2c(%rbp)
L129:
  mov    -0x2c(%rbp),%eax
  cmp    -0x18(%rbp),%eax
  jl     L0
  jmp    L547
L391:
  cmpl   $0x1,-0x40(%rbp)
  jne    L527
  cmpl   $0x0,-0x44(%rbp)
  jne    L527
  mov    -0x20(%rbp),%eax
  sub    -0x64(%rbp),%eax
  mov    %eax,-0x3c(%rbp)
  movl   $0xffffffff,-0x28(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L361
L235:
  mov    -0x3c(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x30(%rbp)
  jmp    L55
L441:
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  addl   $0x1,-0x24(%rbp)
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x30(%rbp)
L55:
  mov    -0x30(%rbp),%eax
  cmp    -0x64(%rbp),%eax
  jl     L441
  mov    -0x64(%rbp),%eax
  sub    %eax,-0x3c(%rbp)
  addl   $0x1,-0x2c(%rbp)
L361:
  mov    -0x2c(%rbp),%eax
  cmp    -0x68(%rbp),%eax
  jl     L235
  mov    -0x1c(%rbp),%eax
  sub    -0x64(%rbp),%eax
  mov    %eax,-0x3c(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L362
L462:
  mov    -0x3c(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x30(%rbp)
  jmp    L136
L458:
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  addl   $0x1,-0x24(%rbp)
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  addl   $0x1,-0x24(%rbp)
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x30(%rbp)
L136:
  mov    -0x30(%rbp),%eax
  cmp    -0x14(%rbp),%eax
  jl     L458
  mov    -0x64(%rbp),%eax
  sub    %eax,-0x3c(%rbp)
  addl   $0x1,-0x2c(%rbp)
L362:
  mov    -0x2c(%rbp),%eax
  cmp    -0x18(%rbp),%eax
  jl     L462
  jmp    L547
L527:
  cmpl   $0x1,-0x40(%rbp)
  jne    L455
  mov    -0x64(%rbp),%eax
  neg    %eax
  jmp    L200
L455:
  mov    -0x64(%rbp),%eax
L200:
  mov    %eax,-0x38(%rbp)
  cmpl   $0x1,-0x40(%rbp)
  jne    L49
  mov    -0x20(%rbp),%eax
  sub    $0x1,%eax
  jmp    L419
L49:
  mov    -0x64(%rbp),%eax
  sub    $0x1,%eax
L419:
  mov    %eax,-0x3c(%rbp)
  movl   $0xffffffff,-0x28(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L24
L275:
  mov    -0x3c(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x30(%rbp)
  jmp    L603
L166:
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  subl   $0x1,-0x24(%rbp)
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x30(%rbp)
L603:
  mov    -0x30(%rbp),%eax
  cmp    -0x64(%rbp),%eax
  jl     L166
  mov    -0x38(%rbp),%eax
  add    %eax,-0x3c(%rbp)
  addl   $0x1,-0x2c(%rbp)
L24:
  mov    -0x2c(%rbp),%eax
  cmp    -0x68(%rbp),%eax
  jl     L275
  cmpl   $0x1,-0x40(%rbp)
  jne    L184
  mov    -0x1c(%rbp),%eax
  sub    $0x1,%eax
  jmp    L417
L184:
  mov    -0x20(%rbp),%edx
  mov    -0x64(%rbp),%eax
  add    %edx,%eax
  sub    $0x1,%eax
L417:
  mov    %eax,-0x3c(%rbp)
  movl   $0x0,-0x2c(%rbp)
  jmp    L491
L139:
  mov    -0x3c(%rbp),%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x30(%rbp)
  jmp    L344
L237:
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    -0x24(%rbp),%edx
  movslq %edx,%rdx
  lea    -0x1(%rdx),%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  addl   $0x1,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    -0x24(%rbp),%edx
  movslq %edx,%rcx
  mov    -0x10(%rbp),%rdx
  add    %rcx,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
  subl   $0x2,-0x24(%rbp)
  addl   $0x1,-0x30(%rbp)
L344:
  mov    -0x30(%rbp),%eax
  cmp    -0x14(%rbp),%eax
  jl     L237
  mov    -0x38(%rbp),%eax
  add    %eax,-0x3c(%rbp)
  addl   $0x1,-0x2c(%rbp)
L491:
  mov    -0x2c(%rbp),%eax
  cmp    -0x18(%rbp),%eax
  jl     L139
L547:
  leave
  ret
```

assistant: ```c
void NV21Transform(const unsigned char *src, const unsigned char *dst, int srcWidth, int srcHeight, int directionFlag) {
  unsigned char *cdst = dst;
  unsigned char *csrc = src;
  int rotate = 0;
  int hflip = 0;
  int vflip = 0;
  if ((0x10 & directionFlag) != 0 || (0x40 & directionFlag) != 0) {
    rotate = 0;
  } else {
    rotate = 1;
  }
  if ((0x10 & directionFlag) != 0 || (0x20 & directionFlag) != 0) {
    hflip = ((0x01 & directionFlag) != 0) ? 1 : 0;
    vflip = ((0x02 & directionFlag) != 0) ? 1 : 0;
  } else {
    if (((0x02 & directionFlag) != 0)) {
      hflip = ((0x01 & directionFlag) != 0) ? 0 : 1;
      vflip = ((0x01 & directionFlag) != 0) ? 0 : 0;
    } else {
      hflip = ((0x01 & directionFlag) != 0) ? 0 : 1;
      vflip = ((0x01 & directionFlag) != 0) ? 1 : 1;
    }
  }
  int ySize = srcHeight * srcWidth;
  int totalSize = ySize * 3 / 2;
  int yStart, yStep, xStep;
  if (rotate == 0 && hflip == 0 && vflip == 0) {
    memcpy(cdst, csrc, totalSize);
    return;
  }
  int srcX, srcY, srcCurr;
  int dstX, dstY, dstCurr;
  int halfHeight = srcHeight >> 1, halfWidth = srcWidth >> 1;
  if (rotate == 1) {
    if (hflip == 1) {
      yStart = vflip == 1 ? ySize - srcHeight : ySize - 1;
      yStep = vflip == 1 ? 1 : -1;
      xStep = -srcHeight;
    } else {
      yStart = vflip == 1 ? 0 : srcHeight - 1;
      yStep = vflip == 1 ? 1 : -1;
      xStep = srcHeight;
    }
    srcCurr = -1;
    for (srcY = 0; srcY < srcHeight; ++srcY) {
      dstCurr = yStart;
      for (srcX = 0; srcX < srcWidth; ++srcX) {
        cdst[dstCurr] = csrc[++srcCurr];
        dstCurr += xStep;
      }
      yStart += yStep;
    }
    if (hflip == 1) {
      yStart = vflip == 1 ? totalSize - srcHeight : totalSize - 2;
      yStep = vflip == 1 ? 2 : -2;
      xStep = -srcHeight;
    } else {
      yStart = vflip == 1 ? ySize : ySize + srcHeight - 2;
      yStep = vflip == 1 ? 2 : -2;
      xStep = srcHeight;
    }
    srcCurr = ySize - 1;
    for (srcY = 0; srcY < halfHeight; ++srcY) {
      dstCurr = yStart;
      for (srcX = 0; srcX < halfWidth; ++srcX) {
        cdst[dstCurr] = csrc[++srcCurr];
        cdst[dstCurr + 1] = csrc[++srcCurr];
        dstCurr += xStep;
      }
      yStart += yStep;
    }
  } else {
    if (vflip == 1 && hflip == 0) {
      yStart = ySize - srcWidth;
      srcCurr = -1;
      for (srcY = 0; srcY < srcHeight; ++srcY) {
        dstCurr = yStart - 1;
        for (srcX = 0; srcX < srcWidth; ++srcX) {
          cdst[++dstCurr] = csrc[++srcCurr];
        }
        yStart -= srcWidth;
      }
      yStart = totalSize - srcWidth;
      for (srcY = 0; srcY < halfHeight; ++srcY) {
        dstCurr = yStart - 1;
        for (srcX = 0; srcX < halfWidth; ++srcX) {
          cdst[++dstCurr] = csrc[++srcCurr];
          cdst[++dstCurr] = csrc[++srcCurr];
        }
        yStart -= srcWidth;
      }
    } else {
      yStep = vflip == 1 ? -srcWidth : srcWidth;
      yStart = vflip == 1 ? ySize - 1 : srcWidth - 1;
      srcCurr = -1;
      for (srcY = 0; srcY < srcHeight; ++srcY) {
        dstCurr = yStart + 1;
        for (srcX = 0; srcX < srcWidth; ++srcX) {
          cdst[--dstCurr] = csrc[++srcCurr];
        }
        yStart += yStep;
      }
      yStart = vflip == 1 ? totalSize - 1 : ySize + srcWidth - 1;
      for (srcY = 0; srcY < halfHeight; ++srcY) {
        dstCurr = yStart;
        for (srcX = 0; srcX < halfWidth; ++srcX) {
          cdst[dstCurr - 1] = csrc[++srcCurr];
          cdst[dstCurr] = csrc[++srcCurr];
          dstCurr -= 2;
        }
        yStart += yStep;
      }
    }
  }
}
```