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

  /* Read file header */
  BMPBITMAPFILEHEADER bmfh;
  bmfh.bfType = WordReadLE(fp);
  bmfh.bfSize = DWordReadLE(fp);
  bmfh.bfReserved1 = WordReadLE(fp);
  bmfh.bfReserved2 = WordReadLE(fp);
  bmfh.bfOffBits = DWordReadLE(fp);
  
  /* Check file header */
  // assert(bmfh.bfType == BMP_BF_TYPE);
  /* ignore bmfh.bfSize */
  /* ignore bmfh.bfReserved1 */
  /* ignore bmfh.bfReserved2 */
  // assert(bmfh.bfOffBits == BMP_BF_OFF_BITS);
  
  /* Read info header */
  BMPBITMAPINFOHEADER bmih;
  bmih.biSize = DWordReadLE(fp);
  bmih.biWidth = LongReadLE(fp);
  bmih.biHeight = LongReadLE(fp);
  bmih.biPlanes = WordReadLE(fp);
  bmih.biBitCount = WordReadLE(fp);
  bmih.biCompression = DWordReadLE(fp);
  bmih.biSizeImage = DWordReadLE(fp);
  bmih.biXPelsPerMeter = LongReadLE(fp);
  bmih.biYPelsPerMeter = LongReadLE(fp);
  bmih.biClrUsed = DWordReadLE(fp);
  bmih.biClrImportant = DWordReadLE(fp);

  // Check if unsupported file type
  // If so, just fill in with default
  if ((bmih.biSize != BMP_BI_SIZE) || (bmih.biPlanes > 1) ||
      (bmih.biBitCount != 24) || (bmih.biCompression != BI_RGB)) {
    RNFail("Unsupported BMP version\n");
    fclose(fp);
    return 0;
  }

  // Check info header 
  assert(bmih.biSize == BMP_BI_SIZE);
  assert(bmih.biWidth > 0);
  assert(bmih.biHeight > 0);
  assert(bmih.biPlanes == 1);
  assert(bmih.biCompression == BI_RGB);   /* RGB */
  int lineLength = bmih.biWidth * bmih.biBitCount / 8;
  if ((lineLength % 4) != 0) lineLength = (lineLength / 4 + 1) * 4;

  // Allocate buffer
  unsigned int buffer_size = lineLength * bmih.biHeight;
  unsigned char *buffer = new unsigned char [buffer_size];
  if (!buffer) {
    RNFail("Unable to allocate memory for BMP file");
    fclose(fp);
    return 0;
  }

  // Read buffer 
  fseek(fp, (long) bmfh.bfOffBits, SEEK_SET);
  if (fread(buffer, 1, buffer_size, fp) != buffer_size) {
    RNFail("Error while reading BMP file %s", filename);
    delete [] buffer;
    return 0;
  }

  // Assign width, height, and ncomponents
  width = bmih.biWidth;
  height = bmih.biHeight;
  ncomponents = (bmih.biBitCount <= 8) ? 1 : 3;
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;

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

  // Copy pixels from buffer
  for (int j = 0; j < height; j++) {
    unsigned char *p = &pixels[j * rowsize];
    unsigned char *b = &buffer[j * lineLength];
    for (int i = 0; i < width; i++) {
      if (bmih.biBitCount == 1) {
        // Binary (this is not right, should be index into color table)
        p[i] = (b[i/8]>>(7-(i%8)) & 0x1) ? 255 : 0;
      }
      else if (bmih.biBitCount == 8) {
        // 8-bit (this is not right, should be index into color table)
        p[i] = b[i];
      }
      else if (bmih.biBitCount == 24) {
        // RGB - swap blue and red in each pixel
        p[i*3+0] = b[i*3+2];
        p[i*3+1] = b[i*3+1];
        p[i*3+2] = b[i*3+0];
      }
    }
  }

  // Delete buffer
  delete [] buffer;

  // Close file
  fclose(fp);

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r15
movq %rdi, %r14
leaq 0x37e91(%rip), %rsi     # 0xa25ae
movq %r15, %rdi
callq 0xe530
testq %rax, %rax
je 0x6a96f
movq %rax, %rbx
movq %r15, 0x20(%rsp)
movq %rax, %rdi
callq 0xe170
movq %rbx, %rdi
callq 0xe170
movq %rbx, %rdi
callq 0x6c18a
movq %rbx, %rdi
callq 0xe170
movq %rbx, %rdi
callq 0xe170
movq %rbx, %rdi
callq 0xe170
movq %rbx, %rdi
callq 0xe170
movq %rbx, %rdi
callq 0x6c18a
movl %eax, 0x14(%rsp)
movq %rbx, %rdi
callq 0x6c18a
movl %eax, 0x8(%rsp)
movq %rbx, %rdi
callq 0x6c1d8
movq %rax, 0x18(%rsp)
movq %rbx, %rdi
callq 0x6c1d8
movl %eax, 0x4(%rsp)
movq %rbx, %rdi
callq 0xe170
movl %eax, %r12d
movq %rbx, %rdi
callq 0xe170
movl %eax, %r15d
movq %rbx, %rdi
callq 0xe170
movl %eax, (%rsp)
movq %rbx, %rdi
callq 0xe170
movl %eax, %r13d
movq %rbx, %rdi
callq 0x6c18a
movl %eax, %ebp
movq %rbx, %rdi
callq 0x6c18a
movq %rbx, %rdi
callq 0x6c1d8
movq %rbx, %rdi
callq 0x6c1d8
movq %rbx, %rdi
callq 0x6c18a
movq %rbx, %rdi
callq 0x6c18a
testl %ebp, %ebp
jne 0x6a985
cmpl $0x28, 0x8(%rsp)
jne 0x6a985
shll $0x8, %r15d
orl %r12d, %r15d
andl $0xfffe, %r15d          # imm = 0xFFFE
jne 0x6a985
shll $0x8, %r13d
orl (%rsp), %r13d
movzwl %r13w, %eax
cmpl $0x18, %eax
jne 0x6a985
movq 0x18(%rsp), %rax
leal (%rax,%rax,2), %r12d
movl %r12d, %eax
testb $0x3, %r12b
je 0x6a85d
leal 0x3(%r12), %eax
testl %r12d, %r12d
cmovnsl %r12d, %eax
andl $-0x4, %eax
addl $0x4, %eax
movl %eax, (%rsp)
movl %eax, %r15d
imull 0x4(%rsp), %r15d
movq %r15, %rdi
callq 0xe030
movq %rax, %rbp
movl 0x14(%rsp), %esi
xorl %r13d, %r13d
movq %rbx, %rdi
xorl %edx, %edx
callq 0xe4d0
movl $0x1, %esi
movq %rbp, 0x8(%rsp)
movq %rbp, %rdi
movq %r15, %rdx
movq %rbx, %rcx
callq 0xe6c0
cmpq %r15, %rax
jne 0x6a9a0
movq 0x8(%rsp), %r15
movq 0x18(%rsp), %rax
movl %eax, (%r14)
movl 0x4(%rsp), %ecx
movl %ecx, 0x4(%r14)
movl $0x3, 0x8(%r14)
testb $0x3, %r12b
je 0x6a8de
leal 0x3(%r12), %eax
testl %r12d, %r12d
cmovnsl %r12d, %eax
andl $-0x4, %eax
addl $0x4, %eax
movl %eax, %r12d
movl %r12d, 0xc(%r14)
imull %r12d, %ecx
movslq %ecx, %rdi
callq 0xe030
movq %rax, 0x10(%r14)
cmpl $0x0, 0x4(%r14)
movq %r15, %rdi
jle 0x6a95a
movslq (%rsp), %rax
xorl %ecx, %ecx
movq %rdi, %rdx
cmpl $0x0, (%r14)
jle 0x6a94b
movslq 0xc(%r14), %rsi
imulq %rcx, %rsi
addq 0x10(%r14), %rsi
movl $0x2, %r10d
xorl %r8d, %r8d
movb (%rdx,%r10), %r9b
movb %r9b, -0x2(%rsi,%r10)
movb -0x1(%rdx,%r10), %r9b
movb %r9b, -0x1(%rsi,%r10)
movb -0x2(%rdx,%r10), %r9b
movb %r9b, (%rsi,%r10)
incq %r8
movslq (%r14), %r9
addq $0x3, %r10
cmpq %r9, %r8
jl 0x6a920
incq %rcx
movslq 0x4(%r14), %rsi
addq %rax, %rdx
cmpq %rsi, %rcx
jl 0x6a905
callq 0xe5b0
movq %rbx, %rdi
callq 0xe430
movl $0x1, %r13d
jmp 0x6a9bd
leaq 0x3f28f(%rip), %rdi     # 0xa9c05
xorl %r13d, %r13d
movq %r15, %rsi
xorl %eax, %eax
callq 0x72a1e
jmp 0x6a9bd
leaq 0x3f297(%rip), %rdi     # 0xa9c23
xorl %r13d, %r13d
xorl %eax, %eax
callq 0x72a1e
movq %rbx, %rdi
callq 0xe430
jmp 0x6a9bd
leaq 0x3f295(%rip), %rdi     # 0xa9c3c
movq 0x20(%rsp), %rsi
xorl %eax, %eax
callq 0x72a1e
movq 0x8(%rsp), %rdi
callq 0xe5b0
movl %r13d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop