// File: /workspace/github_cpp_makefile_star2_O2/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 $0x98, %rsp
movq %rsi, %r15
movq %rdi, %r14
leaq 0x323a9(%rip), %rsi     # 0x9355b
movq %r15, %rdi
callq 0xe550
testq %rax, %rax
je 0x61331
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
movl $0x80, %esi
movq %rax, %rdx
callq 0xe760
testq %rax, %rax
je 0x61346
movq %rbx, %rdi
callq 0xe170
pushq $0x23
popq %rbp
cmpl $0x23, %eax
jne 0x61207
movl %ebp, %r15d
movq %rbx, %rdi
callq 0xe170
cmpl $0xa, %r15d
movl %eax, %r15d
jne 0x611f4
jmp 0x611ec
movl %eax, %edi
movq %rbx, %rsi
callq 0xe0b0
leaq 0x4(%r14), %r12
leaq 0x32489(%rip), %rsi     # 0x936a5
xorl %ebp, %ebp
movq %rbx, %rdi
movq %r14, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0xe870
cmpl $0x2, %eax
jne 0x61351
leaq 0x3b52c(%rip), %rsi     # 0x9c76a
xorl %ebp, %ebp
movq %rsp, %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0xe870
cmpl $0x1, %eax
jne 0x6135a
movl $0x3, 0x8(%r14)
movl (%r14), %ebp
leal (%rbp,%rbp,2), %eax
testb $0x3, %al
je 0x61276
pushq $0x4
popq %rcx
cltd
idivl %ecx
leal 0x4(,%rax,4), %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 0x10(%rsp), %eax
roll $0x18, %eax
cmpl $0x4, %eax
ja 0x61518
leaq 0x397c2(%rip), %rcx     # 0x9aa6c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
testl %r15d, %r15d
jle 0x61508
movslq %r15d, %r15
decq %r15
movslq 0xc(%r14), %r13
imulq %r15, %r13
addq 0x10(%r14), %r13
xorl %r12d, %r12d
cmpl %ebp, %r12d
jge 0x612b3
movq %rbx, %rdi
leaq 0x3b48a(%rip), %rsi     # 0x9c76a
leaq 0x4(%rsp), %rdx
xorl %eax, %eax
callq 0xe870
cmpl $0x1, %eax
jne 0x61532
imull $0xff, 0x4(%rsp), %eax
cltd
idivl (%rsp)
movb %al, (%r13)
imull $0xff, 0x4(%rsp), %eax
cltd
idivl (%rsp)
movb %al, 0x1(%r13)
imull $0xff, 0x4(%rsp), %eax
cltd
idivl (%rsp)
movb %al, 0x2(%r13)
addq $0x3, %r13
incl %r12d
movl (%r14), %ebp
jmp 0x612d1
leaq 0x3986d(%rip), %rdi     # 0x9aba5
xorl %ebp, %ebp
movq %r15, %rsi
xorl %eax, %eax
callq 0x681ca
jmp 0x61370
leaq 0x398af(%rip), %rdi     # 0x9abfc
xorl %ebp, %ebp
jmp 0x61361
leaq 0x398c8(%rip), %rdi     # 0x9ac20
jmp 0x61361
leaq 0x398eb(%rip), %rdi     # 0x9ac4c
xorl %eax, %eax
callq 0x681ca
movq %rbx, %rdi
callq 0xe440
movl %ebp, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testl %r15d, %r15d
jle 0x61508
movslq %r15d, %r15
decq %r15
movslq 0xc(%r14), %r12
imulq %r15, %r12
addq 0x10(%r14), %r12
xorl %r13d, %r13d
cmpl %ebp, %r13d
jge 0x61384
movq %rbx, %rdi
leaq 0x322f2(%rip), %rsi     # 0x936a3
leaq 0x4(%rsp), %rdx
leaq 0xc(%rsp), %rcx
leaq 0x8(%rsp), %r8
xorl %eax, %eax
callq 0xe870
cmpl $0x3, %eax
jne 0x61540
imull $0xff, 0x4(%rsp), %eax
cltd
idivl (%rsp)
movb %al, (%r12)
imull $0xff, 0xc(%rsp), %eax
cltd
idivl (%rsp)
movb %al, 0x1(%r12)
imull $0xff, 0x8(%rsp), %eax
cltd
idivl (%rsp)
movb %al, 0x2(%r12)
incl %r13d
movl (%r14), %ebp
addq $0x3, %r12
jmp 0x613a2
movq %rbx, %rdi
callq 0xe170
movl %eax, %ebp
movl %eax, %edi
callq 0xe080
testl %eax, %eax
jne 0x6142d
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe8c0
movl (%r12), %r15d
testl %r15d, %r15d
jle 0x61508
movslq %r15d, %r15
decq %r15
movslq 0xc(%r14), %r12
imulq %r15, %r12
addq 0x10(%r14), %r12
xorl %ebp, %ebp
cmpl (%r14), %ebp
jge 0x61431
movq %rbx, %rdi
callq 0xe170
imull $0xff, %eax, %eax
cltd
idivl (%rsp)
movb %al, (%r12)
movb %al, 0x1(%r12)
movb %al, 0x2(%r12)
addq $0x3, %r12
incl %ebp
jmp 0x6144e
movq %rbx, %rdi
callq 0xe170
movl %eax, %ebp
movl %eax, %edi
callq 0xe080
testl %eax, %eax
jne 0x6149a
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe8c0
movl (%r12), %r15d
testl %r15d, %r15d
jle 0x61508
movslq %r15d, %r15
decq %r15
movslq 0xc(%r14), %r12
imulq %r15, %r12
addq 0x10(%r14), %r12
xorl %ebp, %ebp
cmpl (%r14), %ebp
jge 0x6149e
movq %rbx, %rdi
callq 0xe170
imull $0xff, %eax, %eax
cltd
idivl (%rsp)
movb %al, (%r12)
movq %rbx, %rdi
callq 0xe170
imull $0xff, %eax, %eax
cltd
idivl (%rsp)
movb %al, 0x1(%r12)
movq %rbx, %rdi
callq 0xe170
imull $0xff, %eax, %eax
cltd
idivl (%rsp)
movb %al, 0x2(%r12)
addq $0x3, %r12
incl %ebp
jmp 0x614b7
movq %rbx, %rdi
callq 0xe440
pushq $0x1
popq %rbp
jmp 0x61370
leaq 0x397b8(%rip), %rdi     # 0x9acd7
xorl %ebp, %ebp
leaq 0x10(%rsp), %rsi
xorl %eax, %eax
callq 0x681ca
jmp 0x61368
leaq 0x3973c(%rip), %rdi     # 0x9ac75
xorl %ebp, %ebp
movl %r12d, %esi
jmp 0x6154c
leaq 0x3975d(%rip), %rdi     # 0x9aca4
xorl %ebp, %ebp
movl %r13d, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x681ca
jmp 0x61368
nop