// File: cloudinary[P]fuif/./import/read_yuv.h
// Function: read_YUV_file(char const*, int, int, int)
Image read_YUV_file(const char *filename, int w, int h, int bitdepth) {
    FILE *fp = NULL;
    if (!strcmp(filename,"-")) fp = stdin;
    else fp = fopen(filename,"rb");

    v_printf(7,"Loading %s as a %ix%i %i-bit YUV file\n",filename,w,h,bitdepth);
    Image image(w, h, (1<<bitdepth) -1, 3);
    int shift = bitdepth-8;
    for (int y=0; y<h; y++) {
        for (int x=0; x<w; x++) {
            image.channel[0].value(y,x) = fgetc(fp);
            if (bitdepth > 8) { image.channel[0].value(y,x) += (fgetc(fp)<<8); }
        }
    }

    for (int c=1; c<3; c++) {
      image.channel[c].w = (w+1)/2;
      image.channel[c].h = (h+1)/2;
      image.channel[c].hshift = 1;
      image.channel[c].vshift = 1;
      image.channel[c].resize();
      for (int y=0; y<(h+1)/2; y++) {
        for (int x=0; x<(w+1)/2; x++) {
            image.channel[c].value(y,x) = fgetc(fp);
            if (bitdepth > 8) { image.channel[c].value(y,x) += (fgetc(fp)<<8); }
        }
      }
    }
    image.transform.push_back(Transform(TRANSFORM_YCbCr));
    Transform subsampling(TRANSFORM_ChromaSubsample);
    subsampling.parameters.push_back(0); // 4:2:0
    image.transform.push_back(subsampling);
    if (fp != stdin) fclose(fp);
    return image;
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0x60(%rsp)
movq %rdi, %rax
movq %rax, 0x68(%rsp)
movq %rdi, 0x100(%rsp)
movq %rsi, 0xf8(%rsp)
movl %edx, 0xf4(%rsp)
movl %ecx, 0xf0(%rsp)
movl %r8d, 0xec(%rsp)
movq $0x0, 0xe0(%rsp)
movq 0xf8(%rsp), %rdi
leaq 0x9cc0(%rip), %rsi      # 0x47955
callq 0x34e0
cmpl $0x0, %eax
jne 0x3dcb3
movq 0x1c32a(%rip), %rax     # 0x59fd0
movq (%rax), %rax
movq %rax, 0xe0(%rsp)
jmp 0x3dccf
movq 0xf8(%rsp), %rdi
leaq 0x9cab(%rip), %rsi      # 0x4796d
callq 0x3460
movq %rax, 0xe0(%rsp)
movq 0xf8(%rsp), %rdx
movl 0xf4(%rsp), %ecx
movl 0xf0(%rsp), %r8d
movl 0xec(%rsp), %r9d
movl $0x7, %edi
leaq 0xa5ec(%rip), %rsi      # 0x482e6
movb $0x0, %al
callq 0x3a770
movq 0x60(%rsp), %rdi
movb $0x0, 0xdf(%rsp)
movl 0xf4(%rsp), %esi
movl 0xf0(%rsp), %edx
movl 0xec(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
subl $0x1, %ecx
movl $0x3, %r8d
xorl %r9d, %r9d
callq 0x25430
movl 0xec(%rsp), %eax
subl $0x8, %eax
movl %eax, 0xd8(%rsp)
movl $0x0, 0xd4(%rsp)
movl 0xd4(%rsp), %eax
cmpl 0xf0(%rsp), %eax
jge 0x3de8f
movl $0x0, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
cmpl 0xf4(%rsp), %eax
jge 0x3de77
movq 0xe0(%rsp), %rdi
callq 0x35c0
movl %eax, 0x5c(%rsp)
jmp 0x3dd9f
movq 0x60(%rsp), %rdi
movl 0x5c(%rsp), %eax
movw %ax, 0x4e(%rsp)
xorl %eax, %eax
movl %eax, %esi
callq 0x4ba0
movq %rax, %rdi
movl 0xd4(%rsp), %esi
movl 0xd0(%rsp), %edx
callq 0x12110
movq %rax, 0x50(%rsp)
jmp 0x3ddd3
movq 0x50(%rsp), %rax
movw 0x4e(%rsp), %cx
movw %cx, (%rax)
cmpl $0x8, 0xec(%rsp)
jle 0x3de5f
movq 0xe0(%rsp), %rdi
callq 0x35c0
movl %eax, 0x48(%rsp)
jmp 0x3ddfd
movq 0x60(%rsp), %rdi
movl 0x48(%rsp), %eax
shll $0x8, %eax
movl %eax, 0x3c(%rsp)
xorl %eax, %eax
movl %eax, %esi
callq 0x4ba0
movq %rax, %rdi
movl 0xd4(%rsp), %esi
movl 0xd0(%rsp), %edx
callq 0x12110
movq %rax, 0x40(%rsp)
jmp 0x3de33
movq 0x40(%rsp), %rax
movl 0x3c(%rsp), %edx
movswl (%rax), %ecx
addl %edx, %ecx
movw %cx, (%rax)
jmp 0x3de5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc8(%rsp)
movl %eax, 0xc4(%rsp)
jmp 0x3e1ef
jmp 0x3de61
movl 0xd0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
jmp 0x3dd78
jmp 0x3de79
movl 0xd4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd4(%rsp)
jmp 0x3dd59
movl $0x1, 0xc0(%rsp)
cmpl $0x3, 0xc0(%rsp)
jge 0x3e0d4
movq 0x60(%rsp), %rdi
movl 0xf4(%rsp), %ecx
movl %ecx, %edx
incl %edx
movl %ecx, %eax
shrl $0x1f, %edx
movl %edx, %ecx
leal 0x1(%rax,%rcx), %eax
sarl %eax
movl %eax, 0x34(%rsp)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movl 0x34(%rsp), %ecx
movq 0x60(%rsp), %rdi
movl %ecx, 0x18(%rax)
movl 0xf0(%rsp), %ecx
movl %ecx, %edx
incl %edx
movl %ecx, %eax
shrl $0x1f, %edx
movl %edx, %ecx
leal 0x1(%rax,%rcx), %eax
sarl %eax
movl %eax, 0x38(%rsp)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movl 0x38(%rsp), %ecx
movq 0x60(%rsp), %rdi
movl %ecx, 0x1c(%rax)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movq 0x60(%rsp), %rdi
movl $0x1, 0x2c(%rax)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movq 0x60(%rsp), %rdi
movl $0x1, 0x30(%rax)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
callq 0x129c0
jmp 0x3df60
movl $0x0, 0xbc(%rsp)
movl 0xbc(%rsp), %eax
movl %eax, 0x30(%rsp)
movl 0xf0(%rsp), %eax
addl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x30(%rsp), %eax
cmpl %ecx, %eax
jge 0x3e0bc
movl $0x0, 0xb8(%rsp)
movl 0xb8(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0xf4(%rsp), %eax
addl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x3e0a4
movq 0xe0(%rsp), %rdi
callq 0x35c0
movl %eax, 0x28(%rsp)
jmp 0x3dfdf
movq 0x60(%rsp), %rdi
movl 0x28(%rsp), %eax
movw %ax, 0x1e(%rsp)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
callq 0x12110
movq %rax, 0x20(%rsp)
jmp 0x3e017
movq 0x20(%rsp), %rax
movw 0x1e(%rsp), %cx
movw %cx, (%rax)
cmpl $0x8, 0xec(%rsp)
jle 0x3e08c
movq 0xe0(%rsp), %rdi
callq 0x35c0
movl %eax, 0x18(%rsp)
jmp 0x3e041
movq 0x60(%rsp), %rdi
movl 0x18(%rsp), %eax
shll $0x8, %eax
movl %eax, 0xc(%rsp)
movslq 0xc0(%rsp), %rsi
callq 0x4ba0
movq %rax, %rdi
movl 0xbc(%rsp), %esi
movl 0xb8(%rsp), %edx
callq 0x12110
movq %rax, 0x10(%rsp)
jmp 0x3e07b
movq 0x10(%rsp), %rax
movl 0xc(%rsp), %edx
movswl (%rax), %ecx
addl %edx, %ecx
movw %cx, (%rax)
jmp 0x3e08e
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x3dfa1
jmp 0x3e0a6
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x3df6b
jmp 0x3e0be
movl 0xc0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc0(%rsp)
jmp 0x3de9a
movq 0x60(%rsp), %rax
addq $0x18, %rax
movq %rax, (%rsp)
leaq 0x98(%rsp), %rdi
xorl %esi, %esi
callq 0x259f0
jmp 0x3e0f2
movq (%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x45350
jmp 0x3e105
leaq 0x98(%rsp), %rdi
callq 0x4b60
leaq 0x78(%rsp), %rdi
movl $0x3, %esi
callq 0x259f0
jmp 0x3e123
leaq 0x80(%rsp), %rdi
movl $0x0, 0x74(%rsp)
leaq 0x74(%rsp), %rsi
callq 0x121b0
jmp 0x3e13f
movq 0x60(%rsp), %rdi
addq $0x18, %rdi
leaq 0x78(%rsp), %rsi
callq 0x4be0
jmp 0x3e154
movq 0xe0(%rsp), %rax
movq 0x1be6d(%rip), %rcx     # 0x59fd0
cmpq (%rcx), %rax
je 0x3e1bc
movq 0xe0(%rsp), %rdi
callq 0x3350
jmp 0x3e177
jmp 0x3e1bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc8(%rsp)
movl %eax, 0xc4(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x4b60
jmp 0x3e1ef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc8(%rsp)
movl %eax, 0xc4(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x4b60
jmp 0x3e1ef
movb $0x1, 0xdf(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x4b60
testb $0x1, 0xdf(%rsp)
jne 0x3e1e2
movq 0x60(%rsp), %rdi
callq 0x12ab0
movq 0x68(%rsp), %rax
addq $0x108, %rsp            # imm = 0x108
retq
movq 0x60(%rsp), %rdi
callq 0x12ab0
movq 0xc8(%rsp), %rdi
callq 0x36a0
nopw %cs:(%rax,%rax)