// File: /workspace/github_cpp_makefile_star2_O2/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 0x31b6d(%rip), %rsi     # 0x93a31
movq %r15, %rdi
callq 0xe550
testq %rax, %rax
je 0x6204c
movq %rax, %r14
movl 0x4(%rbx), %ebp
imull 0xc(%rbx), %ebp
addl $0x36, %ebp
movl $0x4d42, %edi           # imm = 0x4D42
movq %rax, %rsi
callq 0x62631
movl %ebp, %edi
movq %r14, %rsi
callq 0x62655
xorl %r13d, %r13d
xorl %edi, %edi
movq %r14, %rsi
callq 0x62631
xorl %edi, %edi
movq %r14, %rsi
callq 0x62631
pushq $0x36
popq %rdi
movq %r14, %rsi
callq 0x62655
movl (%rbx), %eax
movl %eax, 0x4(%rsp)
movl 0x4(%rbx), %r12d
movl 0x8(%rbx), %ebp
shll $0x3, %ebp
movl 0xc(%rbx), %r15d
imull %r12d, %r15d
pushq $0x28
popq %rdi
movq %r14, %rsi
callq 0x62655
movl 0x4(%rsp), %edi
movq %r14, %rsi
callq 0x6269d
movl %r12d, %edi
movq %r14, %rsi
callq 0x6269d
pushq $0x1
popq %rdi
movq %r14, %rsi
callq 0x62631
movzwl %bp, %edi
movq %r14, %rsi
callq 0x62631
xorl %edi, %edi
movq %r14, %rsi
callq 0x62655
movl %r15d, %edi
movq %r14, %rsi
callq 0x62655
movl $0xb6d, %edi            # imm = 0xB6D
movq %r14, %rsi
callq 0x6269d
movl $0xb6d, %edi            # imm = 0xB6D
movq %r14, %rsi
callq 0x6269d
xorl %edi, %edi
movq %r14, %rsi
callq 0x62655
xorl %edi, %edi
movq %r14, %rsi
callq 0x62655
movl 0x8(%rbx), %eax
movl 0xc(%rbx), %r15d
imull (%rbx), %eax
subl %eax, %r15d
testl %r15d, %r15d
cmovlel %r13d, %r15d
cmpl 0x4(%rbx), %r13d
jge 0x6203f
movslq 0xc(%rbx), %rax
movslq %r13d, %r12
imulq %rax, %r12
addq 0x10(%rbx), %r12
xorl %ebp, %ebp
cmpl (%rbx), %ebp
jge 0x62026
cmpl $0x1, 0x8(%rbx)
jne 0x61ff5
movzbl (%r12), %edi
incq %r12
movq %r14, %rsi
callq 0xe5c0
jmp 0x62022
movzbl 0x2(%r12), %edi
movq %r14, %rsi
callq 0xe5c0
movzbl 0x1(%r12), %edi
movq %r14, %rsi
callq 0xe5c0
movzbl (%r12), %edi
movq %r14, %rsi
callq 0xe5c0
addq $0x3, %r12
incl %ebp
jmp 0x61fd9
movl %r15d, %ebp
subl $0x1, %ebp
jb 0x6203a
xorl %edi, %edi
movq %r14, %rsi
callq 0xe5c0
jmp 0x62029
incl %r13d
jmp 0x61fc2
movq %r14, %rdi
callq 0xe440
pushq $0x1
popq %rbx
jmp 0x6205f
leaq 0x38b52(%rip), %rdi     # 0x9aba5
xorl %ebx, %ebx
movq %r15, %rsi
xorl %eax, %eax
callq 0x681ca
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq