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

    char buf[PPMREADBUFLEN], *t;
    if (!fp) {
        e_printf("Could not open file: %s\n", filename);
        return Image();
    }
    unsigned int width=0,height=0;
    unsigned int maxval=0,nbchans=0;
    do {
        /* # comments before the first line */
        t = fgets(buf, PPMREADBUFLEN, fp);
        if ( t == NULL ) { fclose(fp); return Image(); }
    } while ( strncmp(buf, "#", 1) == 0 || strncmp(buf, "\n", 1) == 0);
    int type=0;
    if ( (!strncmp(buf, "P4", 2)) ) type=4;
    if ( (!strncmp(buf, "P5", 2)) ) type=5;
    if ( (!strncmp(buf, "P6", 2)) ) type=6;
    if ( (!strncmp(buf, "P7", 2)) ) type=7;
    if (type==0) {
        if (buf[0] == 'P') e_printf("PNM file is not of type P4, P5, P6 or P7, cannot read other types.\n");
        else v_printf(8,"This does not look like a PNM file.\n");
        fclose(fp);
        return Image();
    }
    t += 2;

    v_printf(7,"Trying to load a PNM/PAM file of type P%i\n",type);
    if (type < 7) {
      if (!(width = read_pnm_int(fp,buf,&t))) return Image();
      if (!(height = read_pnm_int(fp,buf,&t))) return Image();
      if (type>4) {
        if (!(maxval = read_pnm_int(fp,buf,&t))) return Image();
        if ( maxval > 0xffff ) {
          e_printf("Invalid PNM file (more than 16-bit?)\n");
          fclose(fp);
          return Image();
        }
      } else maxval=1;
      nbchans=(type==6?3:1);
    } else {
      int maxlines = 100;
      do {
        t = fgets(buf, PPMREADBUFLEN, fp);
        if ( t == NULL ) {
            fclose(fp);
            return Image();
        }
        if (strncmp(buf, "#", 1) == 0 || strncmp(buf, "\n", 1) == 0)
            continue;

        sscanf(buf, "WIDTH %u\n", &width);
        sscanf(buf, "HEIGHT %u\n", &height);
        sscanf(buf, "DEPTH %u\n", &nbchans);
        sscanf(buf, "MAXVAL %u\n", &maxval);

        if (maxlines-- < 1) {
            e_printf("Problem while parsing PAM header.\n");
            fclose(fp);
            return Image();
        }
      } while ( strncmp(buf, "ENDHDR", 6) != 0 );
      if (nbchans>4 || nbchans <1 || width <1 || height < 1 || maxval<1 || maxval > 0xffff) {
        e_printf("Couldn't parse PAM header, or unsupported kind of PAM file.\n");
        fclose(fp);
        return Image();
      }
    }

    v_printf(7,"Loading %ix%i PNM/PAM file with %i channels and maxval=%i\n",width,height,nbchans,maxval);
    Image image(width,height, maxval, nbchans);
    if (type==4) {
      char byte=0;
      for (unsigned int y=0; y<height; y++) {
        for (unsigned int x=0; x<width; x++) {
                if (x%8 == 0) byte = fgetc(fp);
                image.channel[0].value(y,x) = (byte & (128>>(x%8)) ? 0 : 1);
        }
      }
    } else {
      if (maxval > 0xff) {
        for (unsigned int y=0; y<height; y++) {
          for (unsigned int x=0; x<width; x++) {
            for (unsigned int c=0; c<nbchans; c++) {
                pixel_type pixel= (fgetc(fp) << 8);
                pixel += fgetc(fp);
                if (pixel > (int)maxval) {
                    fclose(fp);
                    e_printf("Invalid PNM/PAM file: value %i is larger than declared maxval %u\n", pixel, maxval);
                    return Image();
                }
                image.channel[c].value(y,x) = pixel;
            }
          }
        }
      } else {
        for (unsigned int y=0; y<height; y++) {
          for (unsigned int x=0; x<width; x++) {
            for (unsigned int c=0; c<nbchans; c++) {
                image.channel[c].value(y,x) = fgetc(fp);
            }
          }
        }
      }
    }
    if (fp != stdin) fclose(fp);
    return image;
}

// Assembly:
subq $0x278, %rsp            # imm = 0x278
movq %rdi, 0x40(%rsp)
movq %rdi, %rax
movq %rax, 0x48(%rsp)
movq %rdi, 0x270(%rsp)
movq %rsi, 0x268(%rsp)
movq $0x0, 0x260(%rsp)
movq 0x268(%rsp), %rdi
leaq 0xa6b6(%rip), %rsi      # 0x47955
callq 0x34e0
cmpl $0x0, %eax
jne 0x3d2bd
movq 0x1cd20(%rip), %rax     # 0x59fd0
movq (%rax), %rax
movq %rax, 0x260(%rsp)
jmp 0x3d2d9
movq 0x268(%rsp), %rdi
leaq 0xa6a1(%rip), %rsi      # 0x4796d
callq 0x3460
movq %rax, 0x260(%rsp)
cmpq $0x0, 0x260(%rsp)
jne 0x3d309
movq 0x268(%rsp), %rsi
leaq 0xae06(%rip), %rdi      # 0x480f9
movb $0x0, %al
callq 0x3a670
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
movl $0x0, 0x154(%rsp)
movl $0x0, 0x150(%rsp)
movl $0x0, 0x14c(%rsp)
movl $0x0, 0x148(%rsp)
leaq 0x160(%rsp), %rdi
movq 0x260(%rsp), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x35e0
movq %rax, 0x158(%rsp)
cmpq $0x0, 0x158(%rsp)
jne 0x3d37e
movq 0x260(%rsp), %rdi
callq 0x3350
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
jmp 0x3d380
leaq 0x160(%rsp), %rdi
leaq 0xad55(%rip), %rsi      # 0x480e4
movl $0x1, %edx
callq 0x31c0
movl %eax, %ecx
movb $0x1, %al
cmpl $0x0, %ecx
movb %al, 0x3f(%rsp)
je 0x3d3c9
leaq 0x160(%rsp), %rdi
leaq 0xb4f8(%rip), %rsi      # 0x488ad
movl $0x1, %edx
callq 0x31c0
cmpl $0x0, %eax
sete %al
movb %al, 0x3f(%rsp)
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x3d335
movl $0x0, 0x144(%rsp)
leaq 0x160(%rsp), %rdi
leaq 0xad23(%rip), %rsi      # 0x48112
movl $0x2, %edx
callq 0x31c0
cmpl $0x0, %eax
jne 0x3d409
movl $0x4, 0x144(%rsp)
leaq 0x160(%rsp), %rdi
leaq 0xacfd(%rip), %rsi      # 0x48115
movl $0x2, %edx
callq 0x31c0
cmpl $0x0, %eax
jne 0x3d432
movl $0x5, 0x144(%rsp)
leaq 0x160(%rsp), %rdi
leaq 0xacd7(%rip), %rsi      # 0x48118
movl $0x2, %edx
callq 0x31c0
cmpl $0x0, %eax
jne 0x3d45b
movl $0x6, 0x144(%rsp)
leaq 0x160(%rsp), %rdi
leaq 0xacb1(%rip), %rsi      # 0x4811b
movl $0x2, %edx
callq 0x31c0
cmpl $0x0, %eax
jne 0x3d484
movl $0x7, 0x144(%rsp)
cmpl $0x0, 0x144(%rsp)
jne 0x3d4da
movsbl 0x160(%rsp), %eax
cmpl $0x50, %eax
jne 0x3d4ab
leaq 0xac7c(%rip), %rdi      # 0x4811e
movb $0x0, %al
callq 0x3a670
jmp 0x3d4be
movl $0x8, %edi
leaq 0xacab(%rip), %rsi      # 0x48162
movb $0x0, %al
callq 0x3a770
movq 0x260(%rsp), %rdi
callq 0x3350
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
movq 0x158(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x158(%rsp)
movl 0x144(%rsp), %edx
movl $0x7, %edi
leaq 0xac86(%rip), %rsi      # 0x48187
movb $0x0, %al
callq 0x3a770
cmpl $0x7, 0x144(%rsp)
jge 0x3d62f
movq 0x260(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x158(%rsp), %rdx
callq 0x3d140
movl %eax, 0x154(%rsp)
cmpl $0x0, %eax
jne 0x3d54e
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
movq 0x260(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x158(%rsp), %rdx
callq 0x3d140
movl %eax, 0x150(%rsp)
cmpl $0x0, %eax
jne 0x3d586
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
cmpl $0x4, 0x144(%rsp)
jle 0x3d601
movq 0x260(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x158(%rsp), %rdx
callq 0x3d140
movl %eax, 0x14c(%rsp)
cmpl $0x0, %eax
jne 0x3d5c8
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
cmpl $0xffff, 0x14c(%rsp) # imm = 0xFFFF
jbe 0x3d5ff
leaq 0xabd6(%rip), %rdi      # 0x481b2
movb $0x0, %al
callq 0x3a670
movq 0x260(%rsp), %rdi
callq 0x3350
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
jmp 0x3d60c
movl $0x1, 0x14c(%rsp)
movl 0x144(%rsp), %edx
movl $0x1, %eax
movl $0x3, %ecx
cmpl $0x6, %edx
cmovel %ecx, %eax
movl %eax, 0x148(%rsp)
jmp 0x3d80d
movl $0x64, 0x140(%rsp)
leaq 0x160(%rsp), %rdi
movq 0x260(%rsp), %rdx
movl $0x100, %esi            # imm = 0x100
callq 0x35e0
movq %rax, 0x158(%rsp)
cmpq $0x0, 0x158(%rsp)
jne 0x3d683
movq 0x260(%rsp), %rdi
callq 0x3350
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
leaq 0x160(%rsp), %rdi
leaq 0xaa52(%rip), %rsi      # 0x480e4
movl $0x1, %edx
callq 0x31c0
cmpl $0x0, %eax
je 0x3d6bf
leaq 0x160(%rsp), %rdi
leaq 0xb1fd(%rip), %rsi      # 0x488ad
movl $0x1, %edx
callq 0x31c0
cmpl $0x0, %eax
jne 0x3d6c4
jmp 0x3d780
leaq 0x160(%rsp), %rdi
leaq 0xab05(%rip), %rsi      # 0x481d8
leaq 0x154(%rsp), %rdx
movb $0x0, %al
callq 0x3340
leaq 0x160(%rsp), %rdi
leaq 0xaaf1(%rip), %rsi      # 0x481e2
leaq 0x150(%rsp), %rdx
movb $0x0, %al
callq 0x3340
leaq 0x160(%rsp), %rdi
leaq 0xaade(%rip), %rsi      # 0x481ed
leaq 0x148(%rsp), %rdx
movb $0x0, %al
callq 0x3340
leaq 0x160(%rsp), %rdi
leaq 0xaaca(%rip), %rsi      # 0x481f7
leaq 0x14c(%rsp), %rdx
movb $0x0, %al
callq 0x3340
movl 0x140(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, 0x140(%rsp)
cmpl $0x1, %eax
jge 0x3d77e
leaq 0xaaa7(%rip), %rdi      # 0x48202
movb $0x0, %al
callq 0x3a670
movq 0x260(%rsp), %rdi
callq 0x3350
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
jmp 0x3d780
leaq 0x160(%rsp), %rdi
leaq 0xaa96(%rip), %rsi      # 0x48225
movl $0x6, %edx
callq 0x31c0
cmpl $0x0, %eax
jne 0x3d63a
cmpl $0x4, 0x148(%rsp)
ja 0x3d7e1
cmpl $0x1, 0x148(%rsp)
jb 0x3d7e1
cmpl $0x1, 0x154(%rsp)
jb 0x3d7e1
cmpl $0x1, 0x150(%rsp)
jb 0x3d7e1
cmpl $0x1, 0x14c(%rsp)
jb 0x3d7e1
cmpl $0xffff, 0x14c(%rsp) # imm = 0xFFFF
jbe 0x3d80b
leaq 0xaa44(%rip), %rdi      # 0x4822c
movb $0x0, %al
callq 0x3a670
movq 0x260(%rsp), %rdi
callq 0x3350
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3dc22
jmp 0x3d80d
movl 0x154(%rsp), %edx
movl 0x150(%rsp), %ecx
movl 0x148(%rsp), %r8d
movl 0x14c(%rsp), %r9d
movl $0x7, %edi
leaq 0xaa32(%rip), %rsi      # 0x48269
movb $0x0, %al
callq 0x3a770
movl 0x154(%rsp), %esi
movl 0x150(%rsp), %edx
movl 0x14c(%rsp), %ecx
movl 0x148(%rsp), %r8d
leaq 0x90(%rsp), %rdi
xorl %r9d, %r9d
callq 0x25430
cmpl $0x4, 0x144(%rsp)
jne 0x3d99d
movb $0x0, 0x8f(%rsp)
movl $0x0, 0x88(%rsp)
movl 0x88(%rsp), %eax
cmpl 0x150(%rsp), %eax
jae 0x3d998
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
cmpl 0x154(%rsp), %eax
jae 0x3d980
movl 0x84(%rsp), %eax
andl $0x7, %eax
cmpl $0x0, %eax
jne 0x3d90e
movq 0x260(%rsp), %rdi
callq 0x35c0
movl %eax, 0x38(%rsp)
jmp 0x3d8e1
movl 0x38(%rsp), %eax
movb %al, 0x8f(%rsp)
jmp 0x3d90e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x78(%rsp)
movl %eax, 0x74(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x12ab0
jmp 0x3dc2f
movzbl 0x8f(%rsp), %eax
movb 0x84(%rsp), %cl
andb $0x7, %cl
shll %cl, %eax
testb %al, %al
setns %al
movzbl %al, %eax
movw %ax, 0x2e(%rsp)
xorl %eax, %eax
movl %eax, %esi
leaq 0x90(%rsp), %rdi
callq 0x4ba0
movq %rax, %rdi
movl 0x88(%rsp), %esi
movl 0x84(%rsp), %edx
callq 0x12110
movq %rax, 0x30(%rsp)
jmp 0x3d95d
movq 0x30(%rsp), %rax
movw 0x2e(%rsp), %cx
movw %cx, (%rax)
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x3d8ab
jmp 0x3d982
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x3d88c
jmp 0x3dbd6
cmpl $0xff, 0x14c(%rsp)
jbe 0x3db07
movl $0x0, 0x70(%rsp)
movl 0x70(%rsp), %eax
cmpl 0x150(%rsp), %eax
jae 0x3db02
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x154(%rsp), %eax
jae 0x3daf0
movl $0x0, 0x68(%rsp)
movl 0x68(%rsp), %eax
cmpl 0x148(%rsp), %eax
jae 0x3dade
movq 0x260(%rsp), %rdi
callq 0x35c0
movl %eax, 0x28(%rsp)
jmp 0x3da0c
movl 0x28(%rsp), %eax
shll $0x8, %eax
movw %ax, 0x66(%rsp)
movq 0x260(%rsp), %rdi
callq 0x35c0
movl %eax, 0x24(%rsp)
jmp 0x3da2b
movl 0x24(%rsp), %ecx
movswl 0x66(%rsp), %eax
addl %ecx, %eax
movw %ax, 0x66(%rsp)
movswl 0x66(%rsp), %eax
cmpl 0x14c(%rsp), %eax
jle 0x3da8d
movq 0x260(%rsp), %rdi
callq 0x3350
jmp 0x3da58
movswl 0x66(%rsp), %esi
movl 0x14c(%rsp), %edx
leaq 0xa839(%rip), %rdi      # 0x482a4
xorl %eax, %eax
callq 0x3a670
jmp 0x3da74
movq 0x40(%rsp), %rdi
callq 0x1f570
jmp 0x3da80
movl $0x1, 0x60(%rsp)
jmp 0x3dc15
movw 0x66(%rsp), %ax
movw %ax, 0x16(%rsp)
movl 0x68(%rsp), %eax
movl %eax, %esi
leaq 0x90(%rsp), %rdi
callq 0x4ba0
movq %rax, %rdi
movl 0x70(%rsp), %esi
movl 0x6c(%rsp), %edx
callq 0x12110
movq %rax, 0x18(%rsp)
jmp 0x3dac1
movq 0x18(%rsp), %rax
movw 0x16(%rsp), %cx
movw %cx, (%rax)
movl 0x68(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
jmp 0x3d9e8
jmp 0x3dae0
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x3d9cf
jmp 0x3daf2
movl 0x70(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x70(%rsp)
jmp 0x3d9b6
jmp 0x3dbd4
movl $0x0, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
cmpl 0x150(%rsp), %eax
jae 0x3dbd2
movl $0x0, 0x58(%rsp)
movl 0x58(%rsp), %eax
cmpl 0x154(%rsp), %eax
jae 0x3dbc0
movl $0x0, 0x54(%rsp)
movl 0x54(%rsp), %eax
cmpl 0x148(%rsp), %eax
jae 0x3dbae
movq 0x260(%rsp), %rdi
callq 0x35c0
movl %eax, 0x10(%rsp)
jmp 0x3db61
movl 0x10(%rsp), %eax
movw %ax, 0x6(%rsp)
movl 0x54(%rsp), %eax
movl %eax, %esi
leaq 0x90(%rsp), %rdi
callq 0x4ba0
movq %rax, %rdi
movl 0x5c(%rsp), %esi
movl 0x58(%rsp), %edx
callq 0x12110
movq %rax, 0x8(%rsp)
jmp 0x3db94
movq 0x8(%rsp), %rax
movw 0x6(%rsp), %cx
movw %cx, (%rax)
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0x3db41
jmp 0x3dbb0
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x3db28
jmp 0x3dbc2
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x3db0f
jmp 0x3dbd4
jmp 0x3dbd6
movq 0x260(%rsp), %rax
movq 0x1c3eb(%rip), %rcx     # 0x59fd0
cmpq (%rcx), %rax
je 0x3dbfb
movq 0x260(%rsp), %rdi
callq 0x3350
jmp 0x3dbf9
jmp 0x3dbfb
movq 0x40(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x45380
movl $0x1, 0x60(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x12ab0
movq 0x48(%rsp), %rax
addq $0x278, %rsp            # imm = 0x278
retq
movq 0x78(%rsp), %rdi
callq 0x36a0
nopl (%rax)