// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Image.cpp
// Function: gaps::R2Image::ReadPPMFile(char const*)
int R2Image::
ReadPPMFile(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    RNFail("Unable to open image file: %s", filename);
    return 0;
  }

  // Read magic identifier
  char buffer[128];
  if (!fgets(buffer, 128, fp)) {
    RNFail("Unable to read magic id in PPM file");
    fclose(fp);
    return 0;
  }

  // skip comments
  int c = getc(fp);
  while (c == '#') {
    while (c != '\n') c = getc(fp);
    c = getc(fp);
  }
  ungetc(c, fp);

  // Read width and height
  if (fscanf(fp, "%d%d", &width, &height) != 2) {
    RNFail("Unable to read width and height in PPM file");
    fclose(fp);
    return 0;
  }
	
  // Read max value
  int max_value;
  if (fscanf(fp, "%d", &max_value) != 1) {
    RNFail("Unable to read max_value in PPM file");
    fclose(fp);
    return 0;
  }
	
  // Assign ncomponents and rowsize
  ncomponents = 3;
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;

  // Allocate image pixels
  int nbytes = rowsize * height;
  pixels = new unsigned char [nbytes];
  if (!pixels) {
    RNFail("Unable to allocate memory for PPM file");
    fclose(fp);
    return 0;
  }

  // Check file type
  if (!strcmp(buffer, "P2\n")) {
    // Read asci gray image data 
    for (int j = height-1; j >= 0; j--) {
      unsigned char *p = &pixels[j*rowsize];
      for (int i = 0; i < width; i++) {
	// Read pixel values
	int value;
	if (fscanf(fp, "%d", &value) != 1) {
	  RNFail("Unable to read data at (%d,%d) in PGM file", i, j);
	  fclose(fp);
	  return 0;
	}

	// Assign pixel values
	*(p++) = ((255 * value) / max_value) & 0xFF;
	*(p++) = ((255 * value) / max_value) & 0xFF;
	*(p++) = ((255 * value) / max_value) & 0xFF;
      }
    }
  }
  else if (!strcmp(buffer, "P3\n")) {
    // Read asci rgb image data 
    for (int j = height-1; j >= 0; j--) {
      unsigned char *p = &pixels[j*rowsize];
      for (int i = 0; i < width; i++) {
	// Read pixel values
	int r, g, b;
	if (fscanf(fp, "%d%d%d", &r, &g, &b) != 3) {
	  RNFail("Unable to read data at (%d,%d) in PPM file", i, j);
	  fclose(fp);
	  return 0;
	}

	// Assign pixel values
	*(p++) = ((255 * r) / max_value) & 0xFF;
	*(p++) = ((255 * g) / max_value) & 0xFF;
	*(p++) = ((255 * b) / max_value) & 0xFF;
      }
    }
  }
  else if (!strcmp(buffer, "P5\n")) {
    // Read up to one character of whitespace (\n) after max_value
    int c = getc(fp);
    if (!isspace(c)) putc(c, fp);

    // Read binary gray image data 
    // First pgm pixel is top-left, so read in opposite scan-line order
    for (int j = height-1; j >= 0; j--) {
      unsigned char *p = &pixels[j*rowsize];
      for (int i = 0; i < width; i++) {
	// Read pixel values
        unsigned char value = ((255 * getc(fp)) / max_value) & 0xFF;
	*(p++) = value;
	*(p++) = value;
	*(p++) = value;
      }
    }
  }
  else if (!strcmp(buffer, "P6\n")) {
    // Read up to one character of whitespace (\n) after max_value
    int c = getc(fp);
    if (!isspace(c)) putc(c, fp);

    // Read binary rgb image data 
    // First ppm pixel is top-left, so read in opposite scan-line order
    for (int j = height-1; j >= 0; j--) {
      unsigned char *p = &pixels[j*rowsize];
      for (int i = 0; i < width; i++) {
	// Read pixel values
	*(p++) = ((255 * getc(fp)) / max_value) & 0xFF;
	*(p++) = ((255 * getc(fp)) / max_value) & 0xFF;
	*(p++) = ((255 * getc(fp)) / max_value) & 0xFF;
      }
    }
  }
  else {
    RNFail("Unrecognized magic header in pbm file: %s\n", buffer);
    fclose(fp);
    return 0;
  }

  // Close file
  fclose(fp);

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %r15
movq %rdi, %r14
leaq 0x38747(%rip), %rsi     # 0xa25ab
movq %r15, %rdi
callq 0xe530
testq %rax, %rax
je 0x6a009
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
movl $0x80, %esi
movq %rax, %rdx
callq 0xe730
testq %rax, %rax
jne 0x69eaa
leaq 0x3fde6(%rip), %rdi     # 0xa9c7c
xorl %ebp, %ebp
jmp 0x6a02e
movq %rbx, %rdi
callq 0xe170
cmpl $0xa, %eax
jne 0x69e9d
movq %rbx, %rdi
callq 0xe170
cmpl $0x23, %eax
je 0x69e9d
movl %eax, %edi
movq %rbx, %rsi
callq 0xe0b0
leaq 0x4(%r14), %r12
leaq 0x38829(%rip), %rsi     # 0xa26f5
xorl %ebp, %ebp
movq %rbx, %rdi
movq %r14, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0xe840
cmpl $0x2, %eax
jne 0x6a01e
leaq 0x41b5c(%rip), %rsi     # 0xaba4a
xorl %ebp, %ebp
leaq 0xc(%rsp), %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0xe840
cmpl $0x1, %eax
jne 0x6a027
movl $0x3, 0x8(%r14)
movl (%r14), %ebp
leal (%rbp,%rbp,2), %eax
testb $0x3, %al
je 0x69f2b
leal 0x3(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
andl $-0x4, %ecx
addl $0x4, %ecx
movl %ecx, %eax
movl %eax, 0xc(%r14)
movl 0x4(%r14), %r15d
imull %r15d, %eax
movslq %eax, %rdi
callq 0xe030
movq %rax, 0x10(%r14)
movl $0xfff5cdb0, %eax       # imm = 0xFFF5CDB0
addl 0x20(%rsp), %eax
roll $0x18, %eax
cmpl $0x4, %eax
ja 0x6a249
leaq 0x3fb85(%rip), %rcx     # 0xa9ae4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
testl %r15d, %r15d
jle 0x6a237
movl %r15d, 0x14(%rsp)
movslq %r15d, %r15
decq %r15
testl %ebp, %ebp
jle 0x69ff9
movslq 0xc(%r14), %r13
imulq %r15, %r13
addq 0x10(%r14), %r13
xorl %r12d, %r12d
movq %rbx, %rdi
leaq 0x41ab1(%rip), %rsi     # 0xaba4a
leaq 0x10(%rsp), %rdx
xorl %eax, %eax
callq 0xe840
cmpl $0x1, %eax
jne 0x6a263
movl 0x10(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, (%r13)
movl 0x10(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, 0x1(%r13)
movl 0x10(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, 0x2(%r13)
incl %r12d
movl (%r14), %ebp
addq $0x3, %r13
cmpl %ebp, %r12d
jl 0x69f8f
cmpl $0x2, 0x14(%rsp)
jge 0x69f71
jmp 0x6a237
leaq 0x3fc15(%rip), %rdi     # 0xa9c25
xorl %ebp, %ebp
movq %r15, %rsi
xorl %eax, %eax
callq 0x719d2
jmp 0x6a03d
leaq 0x3fc7b(%rip), %rdi     # 0xa9ca0
jmp 0x6a02e
leaq 0x3fc9e(%rip), %rdi     # 0xa9ccc
xorl %eax, %eax
callq 0x719d2
movq %rbx, %rdi
callq 0xe430
movl %ebp, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
callq 0xe170
movl %eax, %ebp
movl %eax, %edi
callq 0xe080
testl %eax, %eax
jne 0x6a070
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe890
movl (%r12), %ebp
testl %ebp, %ebp
jle 0x6a237
movl (%r14), %eax
movslq %ebp, %r15
decq %r15
testl %eax, %eax
jle 0x6a0cb
movslq 0xc(%r14), %r12
imulq %r15, %r12
addq 0x10(%r14), %r12
xorl %r13d, %r13d
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, (%r12)
movb %al, 0x1(%r12)
movb %al, 0x2(%r12)
addq $0x3, %r12
incl %r13d
movl (%r14), %eax
cmpl %eax, %r13d
jl 0x6a098
cmpl $0x2, %ebp
movl %r15d, %ebp
jge 0x6a07f
jmp 0x6a237
testl %r15d, %r15d
jle 0x6a237
movl %r15d, 0x14(%rsp)
movslq %r15d, %r15
decq %r15
testl %ebp, %ebp
jle 0x6a179
movslq 0xc(%r14), %r12
imulq %r15, %r12
addq 0x10(%r14), %r12
xorl %r13d, %r13d
movq %rbx, %rdi
leaq 0x385e6(%rip), %rsi     # 0xa26f3
leaq 0x10(%rsp), %rdx
leaq 0x1c(%rsp), %rcx
leaq 0x18(%rsp), %r8
xorl %eax, %eax
callq 0xe840
cmpl $0x3, %eax
jne 0x6a271
movl 0x10(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, (%r12)
movl 0x1c(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, 0x1(%r12)
movl 0x18(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, 0x2(%r12)
incl %r13d
movl (%r14), %ebp
addq $0x3, %r12
cmpl %ebp, %r13d
jl 0x6a103
cmpl $0x2, 0x14(%rsp)
jge 0x6a0e1
jmp 0x6a237
movq %rbx, %rdi
callq 0xe170
movl %eax, %ebp
movl %eax, %edi
callq 0xe080
testl %eax, %eax
jne 0x6a1a8
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe890
movl (%r12), %ebp
testl %ebp, %ebp
jle 0x6a237
movl (%r14), %eax
movslq %ebp, %r15
decq %r15
testl %eax, %eax
jle 0x6a22f
movslq 0xc(%r14), %r12
imulq %r15, %r12
addq 0x10(%r14), %r12
xorl %r13d, %r13d
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, (%r12)
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, 0x1(%r12)
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl 0xc(%rsp)
movb %al, 0x2(%r12)
addq $0x3, %r12
incl %r13d
movl (%r14), %eax
cmpl %eax, %r13d
jl 0x6a1d0
cmpl $0x2, %ebp
movl %r15d, %ebp
jge 0x6a1b7
movq %rbx, %rdi
callq 0xe430
movl $0x1, %ebp
jmp 0x6a03d
leaq 0x3fb07(%rip), %rdi     # 0xa9d57
xorl %ebp, %ebp
leaq 0x20(%rsp), %rsi
xorl %eax, %eax
callq 0x719d2
jmp 0x6a035
leaq 0x3fa8b(%rip), %rdi     # 0xa9cf5
xorl %ebp, %ebp
movl %r12d, %esi
jmp 0x6a27d
leaq 0x3faac(%rip), %rdi     # 0xa9d24
xorl %ebp, %ebp
movl %r13d, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x719d2
jmp 0x6a035