// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Image.cpp
// Function: gaps::R2Image::WriteBMPFile(char const*) const
int R2Image::
WriteBMPFile(const char *filename) const
{
  // Check ncomponents
  assert(ncomponents == 3);

  // Open file
  FILE *fp = fopen(filename, "wb");
  if (!fp) {
    RNFail("Unable to open image file: %s", filename);
    return 0;
  }

  // Write file header 
  BMPBITMAPFILEHEADER bmfh;
  bmfh.bfType = BMP_BF_TYPE;
  bmfh.bfSize = BMP_BF_OFF_BITS + rowsize * height;
  bmfh.bfReserved1 = 0;
  bmfh.bfReserved2 = 0;
  bmfh.bfOffBits = BMP_BF_OFF_BITS;
  WordWriteLE(bmfh.bfType, fp);
  DWordWriteLE(bmfh.bfSize, fp);
  WordWriteLE(bmfh.bfReserved1, fp);
  WordWriteLE(bmfh.bfReserved2, fp);
  DWordWriteLE(bmfh.bfOffBits, fp);

  // Write info header 
  BMPBITMAPINFOHEADER bmih;
  bmih.biSize = BMP_BI_SIZE;
  bmih.biWidth = width;
  bmih.biHeight = height;
  bmih.biPlanes = 1;
  bmih.biBitCount = 8 * ncomponents;
  bmih.biCompression = BI_RGB;   
  bmih.biSizeImage = rowsize * (unsigned int) bmih.biHeight;  
  bmih.biXPelsPerMeter = 2925;
  bmih.biYPelsPerMeter = 2925;
  bmih.biClrUsed = 0;
  bmih.biClrImportant = 0;
  DWordWriteLE(bmih.biSize, fp);
  LongWriteLE(bmih.biWidth, fp);
  LongWriteLE(bmih.biHeight, fp);
  WordWriteLE(bmih.biPlanes, fp);
  WordWriteLE(bmih.biBitCount, fp);
  DWordWriteLE(bmih.biCompression, fp);
  DWordWriteLE(bmih.biSizeImage, fp);
  LongWriteLE(bmih.biXPelsPerMeter, fp);
  LongWriteLE(bmih.biYPelsPerMeter, fp);
  DWordWriteLE(bmih.biClrUsed, fp);
  DWordWriteLE(bmih.biClrImportant, fp);

  // Write image
  int pad = rowsize - width * ncomponents;
  for (int j = 0; j < height; j++) {
    // Write row of pixels BGR
    unsigned char *p = &pixels[j * rowsize];
    for (int i = 0; i < width; i++) {
      if (ncomponents == 1) {
        // Write gray value
        fputc(*(p++), fp);
      }
      else {
        // Write BRG, swapping blue and red in each pixel
        fputc(*(p+2), fp);
        fputc(*(p+1), fp);
        fputc(*(p+0), fp);
        p += 3;
      }
    }

    // Pad row
    for (int i = 0; i < pad; i++) fputc(0, fp);
  }
  
  // Close file
  fclose(fp);

  // Return success
  return 1;  
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x37e35(%rip), %rsi     # 0xa2a81
movq %r15, %rdi
callq 0xe530
testq %rax, %rax
je 0x6ae2a
movq %rax, %r14
movl 0x4(%rbx), %ebp
imull 0xc(%rbx), %ebp
addl $0x36, %ebp
movl $0x42, %edi
movq %rax, %rsi
callq 0xe890
movl $0x4d, %edi
movq %r14, %rsi
callq 0xe890
movl %ebp, %edi
movq %r14, %rsi
callq 0x6b47d
xorl %r15d, %r15d
xorl %edi, %edi
movq %r14, %rsi
callq 0xe890
xorl %edi, %edi
movq %r14, %rsi
callq 0xe890
xorl %edi, %edi
movq %r14, %rsi
callq 0xe890
xorl %edi, %edi
movq %r14, %rsi
callq 0xe890
movl $0x36, %edi
movq %r14, %rsi
callq 0x6b47d
movl (%rbx), %eax
movl %eax, (%rsp)
movl 0x4(%rbx), %ebp
movl 0x8(%rbx), %r12d
leal (,%r12,8), %r13d
movl 0xc(%rbx), %eax
imull %ebp, %eax
movl %eax, 0x4(%rsp)
movl $0x28, %edi
movq %r14, %rsi
callq 0x6b47d
movl (%rsp), %edi
movq %r14, %rsi
callq 0x6b4c5
movl %ebp, %edi
movq %r14, %rsi
callq 0x6b4c5
movl $0x1, %edi
movq %r14, %rsi
callq 0xe890
xorl %edi, %edi
movq %r14, %rsi
callq 0xe890
movl $0xff, %ebp
andl %ebp, %r13d
movl %r13d, %edi
movq %r14, %rsi
callq 0xe890
shrl $0x5, %r12d
andl %ebp, %r12d
movl %r12d, %edi
movq %r14, %rsi
callq 0xe890
xorl %edi, %edi
movq %r14, %rsi
callq 0x6b47d
movl 0x4(%rsp), %edi
movq %r14, %rsi
callq 0x6b47d
movl $0xb6d, %edi            # imm = 0xB6D
movq %r14, %rsi
callq 0x6b4c5
movl $0xb6d, %edi            # imm = 0xB6D
movq %r14, %rsi
callq 0x6b4c5
xorl %edi, %edi
movq %r14, %rsi
callq 0x6b47d
xorl %edi, %edi
movq %r14, %rsi
callq 0x6b47d
cmpl $0x0, 0x4(%rbx)
jle 0x6ae1b
movl 0x8(%rbx), %eax
movl 0xc(%rbx), %r12d
imull (%rbx), %eax
subl %eax, %r12d
cmpl $0x0, (%rbx)
jle 0x6adfc
movslq 0xc(%rbx), %rax
movslq %r15d, %r13
imulq %rax, %r13
addq 0x10(%rbx), %r13
xorl %ebp, %ebp
cmpl $0x1, 0x8(%rbx)
jne 0x6adcb
movzbl (%r13), %edi
incq %r13
movq %r14, %rsi
callq 0xe5a0
jmp 0x6adf6
movzbl 0x2(%r13), %edi
movq %r14, %rsi
callq 0xe5a0
movzbl 0x1(%r13), %edi
movq %r14, %rsi
callq 0xe5a0
movzbl (%r13), %edi
movq %r14, %rsi
callq 0xe5a0
addq $0x3, %r13
incl %ebp
cmpl (%rbx), %ebp
jl 0x6adb3
movl %r12d, %ebp
testl %r12d, %r12d
jle 0x6ae12
xorl %edi, %edi
movq %r14, %rsi
callq 0xe5a0
decl %ebp
jne 0x6ae04
incl %r15d
cmpl 0x4(%rbx), %r15d
jl 0x6ad9d
movq %r14, %rdi
callq 0xe430
movl $0x1, %ebx
jmp 0x6ae3d
leaq 0x3edf4(%rip), %rdi     # 0xa9c25
xorl %ebx, %ebx
movq %r15, %rsi
xorl %eax, %eax
callq 0x719d2
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq