// File: /workspace/github_cpp_makefile_star2_O1/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 0x379b0(%rip), %rsi     # 0xa25ae
movq %r15, %rdi
callq 0xe530
testq %rax, %rax
je 0x6adde
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
movl $0x80, %esi
movq %rax, %rdx
callq 0xe730
testq %rax, %rax
jne 0x6ac44
leaq 0x3f02c(%rip), %rdi     # 0xa9c5c
xorl %ebp, %ebp
jmp 0x6ae03
movq %rbx, %rdi
callq 0xe170
cmpl $0xa, %eax
jne 0x6ac37
movq %rbx, %rdi
callq 0xe170
cmpl $0x23, %eax
je 0x6ac37
movl %eax, %edi
movq %rbx, %rsi
callq 0xe0b0
leaq 0x4(%r14), %r12
leaq 0x37a92(%rip), %rsi     # 0xa26f8
xorl %ebp, %ebp
movq %rbx, %rdi
movq %r14, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0xe840
cmpl $0x2, %eax
jne 0x6adf3
leaq 0x40d82(%rip), %rsi     # 0xaba0a
xorl %ebp, %ebp
movq %rsp, %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0xe840
cmpl $0x1, %eax
jne 0x6adfc
movl $0x3, 0x8(%r14)
movl (%r14), %eax
leal (%rax,%rax,2), %eax
testb $0x3, %al
je 0x6acc2
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), %ecx
movq %rcx, 0x8(%rsp)
imull %ecx, %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 0x6b047
leaq 0x3edc2(%rip), %rcx     # 0xa9abc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x1, %ebp
cmpl $0x0, 0x8(%rsp)
jle 0x6ae0a
movq 0x8(%rsp), %rax
movl %eax, 0x14(%rsp)
cltq
decq %rax
movq %rax, 0x8(%rsp)
cmpl $0x0, (%r14)
jle 0x6add1
movslq 0xc(%r14), %r15
imulq 0x8(%rsp), %r15
addq 0x10(%r14), %r15
xorl %r12d, %r12d
movq %rbx, %rdi
leaq 0x40cbf(%rip), %rsi     # 0xaba0a
leaq 0x4(%rsp), %rdx
xorl %eax, %eax
callq 0xe840
movl %eax, %r13d
cmpl $0x1, %eax
jne 0x6ad9d
movl 0x4(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl (%rsp)
movb %al, (%r15)
movl 0x4(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl (%rsp)
movb %al, 0x1(%r15)
movl 0x4(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl (%rsp)
movb %al, 0x2(%r15)
addq $0x3, %r15
jmp 0x6adbb
leaq 0x3ef31(%rip), %rdi     # 0xa9cd5
movl %r12d, %esi
movq 0x8(%rsp), %rdx
xorl %eax, %eax
callq 0x72a1e
movq %rbx, %rdi
callq 0xe430
cmpl $0x1, %r13d
jne 0x6af8c
incl %r12d
cmpl (%r14), %r12d
jl 0x6ad41
cmpl $0x2, 0x14(%rsp)
jge 0x6ad13
jmp 0x6ae0a
leaq 0x3ee20(%rip), %rdi     # 0xa9c05
xorl %ebp, %ebp
movq %r15, %rsi
xorl %eax, %eax
callq 0x72a1e
jmp 0x6ae12
leaq 0x3ee86(%rip), %rdi     # 0xa9c80
jmp 0x6ae03
leaq 0x3eea9(%rip), %rdi     # 0xa9cac
xorl %eax, %eax
callq 0x72a1e
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 0x6ae45
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe890
movl (%r12), %ebp
testl %ebp, %ebp
jle 0x6b03d
movslq %ebp, %r15
decq %r15
cmpl $0x0, (%r14)
jle 0x6ae9b
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 (%rsp)
movb %al, (%r12)
movb %al, 0x1(%r12)
movb %al, 0x2(%r12)
addq $0x3, %r12
incl %r13d
cmpl (%r14), %r13d
jl 0x6ae6c
cmpl $0x2, %ebp
movl %r15d, %ebp
jge 0x6ae51
jmp 0x6b03d
movl $0x1, %ebp
cmpl $0x0, 0x8(%rsp)
jle 0x6ae0a
movq 0x8(%rsp), %rax
movl %eax, 0x14(%rsp)
cltq
decq %rax
movq %rax, 0x8(%rsp)
cmpl $0x0, (%r14)
jle 0x6af7c
movslq 0xc(%r14), %r15
imulq 0x8(%rsp), %r15
addq 0x10(%r14), %r15
xorl %r12d, %r12d
movq %rbx, %rdi
leaq 0x37806(%rip), %rsi     # 0xa26f6
leaq 0x4(%rsp), %rdx
leaq 0x1c(%rsp), %rcx
leaq 0x18(%rsp), %r8
xorl %eax, %eax
callq 0xe840
movl %eax, %r13d
cmpl $0x3, %eax
jne 0x6af4c
movl 0x4(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl (%rsp)
movb %al, (%r15)
movl 0x1c(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl (%rsp)
movb %al, 0x1(%r15)
movl 0x18(%rsp), %ecx
movl %ecx, %eax
shll $0x8, %eax
subl %ecx, %eax
cltd
idivl (%rsp)
movb %al, 0x2(%r15)
addq $0x3, %r15
jmp 0x6af6a
leaq 0x3edb1(%rip), %rdi     # 0xa9d04
movl %r12d, %esi
movq 0x8(%rsp), %rdx
xorl %eax, %eax
callq 0x72a1e
movq %rbx, %rdi
callq 0xe430
cmpl $0x3, %r13d
jne 0x6af8c
incl %r12d
cmpl (%r14), %r12d
jl 0x6aee6
cmpl $0x2, 0x14(%rsp)
jge 0x6aeb8
jmp 0x6ae0a
xorl %ebp, %ebp
jmp 0x6ae12
movq %rbx, %rdi
callq 0xe170
movl %eax, %ebp
movl %eax, %edi
callq 0xe080
testl %eax, %eax
jne 0x6afb2
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe890
movl (%r12), %r15d
movl $0x1, %ebp
testl %r15d, %r15d
jle 0x6ae0a
movslq %r15d, %r12
decq %r12
cmpl $0x0, (%r14)
jle 0x6b034
movslq 0xc(%r14), %r13
imulq %r12, %r13
addq 0x10(%r14), %r13
xorl %ebp, %ebp
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl (%rsp)
movb %al, (%r13)
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl (%rsp)
movb %al, 0x1(%r13)
movq %rbx, %rdi
callq 0xe170
movl %eax, %ecx
shll $0x8, %ecx
subl %eax, %ecx
movl %ecx, %eax
cltd
idivl (%rsp)
movb %al, 0x2(%r13)
addq $0x3, %r13
incl %ebp
cmpl (%r14), %ebp
jl 0x6afde
cmpl $0x2, %r15d
movl %r12d, %r15d
jge 0x6afc4
movl $0x1, %ebp
jmp 0x6ae0a
leaq 0x3ece9(%rip), %rdi     # 0xa9d37
xorl %ebp, %ebp
leaq 0x20(%rsp), %rsi
xorl %eax, %eax
callq 0x72a1e
jmp 0x6ae0a
nop