/*
BMP File Reader/Writer Implementation
Anton Gerdelan
Version: 3
Licence: see apg_bmp.h
C99
*/

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS 1
#endif

#include "apg_bmp.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Maximum pixel dimensions of width or height of an image. Should accommodate max used in graphics APIs.
   NOTE: 65536*65536 is the biggest number storable in 32 bits.
   This needs to be multiplied by n_channels so actual memory indices are not uint32 but size_t to avoid overflow.
   Note this will crash stb_image_write et al at maximum size which use 32bits, so reduce max size to accom. */
#define _BMP_MAX_DIMS 65536
#define _BMP_FILE_HDR_SZ 14
#define _BMP_MIN_DIB_HDR_SZ 40
#define _BMP_MIN_HDR_SZ ( _BMP_FILE_HDR_SZ + _BMP_MIN_DIB_HDR_SZ )
#define _BMP_MAX_IMAGE_FILE_SIZE (1024ULL*1024ULL*1024ULL)

#pragma pack( push, 1 ) // supported on GCC in addition to individual packing attribs
/* All BMP files, regardless of type, start with this file header */
typedef struct _bmp_file_header_t {
  char file_type[2];
  uint32_t file_sz;
  uint16_t reserved1;
  uint16_t reserved2;
  uint32_t image_data_offset;
} _bmp_file_header_t;

/* Following the file header is the BMP type header. this is the most commonly used format */
typedef struct _bmp_dib_BITMAPINFOHEADER_t {
  uint32_t this_header_sz;
  int32_t w;                      // in older headers w & h these are shorts and may be unsigned
  int32_t h;                      //
  uint16_t n_planes;              // must be 1
  uint16_t bpp;                   // bits per pixel. 1,4,8,16,24,32.
  uint32_t compression_method;    // 16 and 32-bit images must have a value of 3 here
  uint32_t image_uncompressed_sz; // not consistently used in the wild, so ignored here.
  int32_t horiz_pixels_per_meter; // not used.
  int32_t vert_pixels_per_meter;  // not used.
  uint32_t n_colours_in_palette;  //
  uint32_t n_important_colours;   // not used.
  /* NOTE(Anton) a DIB header may end here at 40-bytes. be careful using sizeof() */
  /* if 'compression' value, above, is set to 3 ie the image is 16 or 32-bit, then these colour channel masks follow the headers.
  these are big-endian order bit masks to assign bits of each pixel to different colours. bits used must be contiguous and not overlap. */
  uint32_t bitmask_r;
  uint32_t bitmask_g;
  uint32_t bitmask_b;
} _bmp_dib_BITMAPINFOHEADER_t;
#pragma pack( pop )

typedef enum _bmp_compression_t {
  BI_RGB            = 0,
  BI_RLE8           = 1,
  BI_RLE4           = 2,
  BI_BITFIELDS      = 3,
  BI_JPEG           = 4,
  BI_PNG            = 5,
  BI_ALPHABITFIELDS = 6,
  BI_CMYK           = 11,
  BI_CMYKRLE8       = 12,
  BI_CMYRLE4        = 13
} _bmp_compression_t;

/* convenience struct and file->memory function */
typedef struct _entire_file_t {
  void* data;
  size_t sz;
} _entire_file_t;

/*
RETURNS
- true on success. record->data is allocated memory and must be freed by the caller.
- false on any error. Any allocated memory is freed if false is returned */
static bool _read_entire_file( const char* filename, _entire_file_t* record ) {
  FILE* fp = fopen( filename, "rb" );
  if ( !fp ) { return false; }
  fseek( fp, 0L, SEEK_END );
  record->sz   = (size_t)ftell( fp );

  // Immediately bail on anything larger than _BMP_MAX_IMAGE_FILE_SIZE. 
  if (record->sz > _BMP_MAX_IMAGE_FILE_SIZE) {
    fclose( fp );
    return false;
  }

  record->data = malloc( record->sz );
  if ( !record->data ) {
    fclose( fp );
    return false;
  }
  rewind( fp );
  size_t nr = fread( record->data, record->sz, 1, fp );
  fclose( fp );
  if ( 1 != nr ) { return false; }
  return true;
}

static bool _validate_file_hdr( _bmp_file_header_t* file_hdr_ptr, size_t file_sz ) {
  if ( !file_hdr_ptr ) { return false; }
  if ( file_hdr_ptr->file_type[0] != 'B' || file_hdr_ptr->file_type[1] != 'M' ) { return false; }
  if ( file_hdr_ptr->image_data_offset > file_sz ) { return false; }
  return true;
}

static bool _validate_dib_hdr( _bmp_dib_BITMAPINFOHEADER_t* dib_hdr_ptr, size_t file_sz ) {
  if ( !dib_hdr_ptr ) { return false; }
  if ( _BMP_FILE_HDR_SZ + dib_hdr_ptr->this_header_sz > file_sz ) { return false; }
  if ( ( 32 == dib_hdr_ptr->bpp || 16 == dib_hdr_ptr->bpp ) && ( BI_BITFIELDS != dib_hdr_ptr->compression_method && BI_ALPHABITFIELDS != dib_hdr_ptr->compression_method ) ) {
    return false;
  }
  if ( BI_RGB != dib_hdr_ptr->compression_method && BI_BITFIELDS != dib_hdr_ptr->compression_method && BI_ALPHABITFIELDS != dib_hdr_ptr->compression_method ) {
    return false;
  }
  // NOTE(Anton) using abs() in the if-statement was blowing up on large negative numbers. switched to labs()
  if ( 0 == dib_hdr_ptr->w || 0 == dib_hdr_ptr->h || labs( dib_hdr_ptr->w ) > _BMP_MAX_DIMS || labs( dib_hdr_ptr->h ) > _BMP_MAX_DIMS ) { return false; }

  /* NOTE(Anton) if images reliably used n_colours_in_palette we could have done a palette/file size integrity check here.
  because some always set 0 then we have to check every palette indexing as we read them */
  return true;
}

/* NOTE(Anton) this could have ifdef branches on different compilers for the intrinsics versions for perf */
static uint32_t _bitscan( uint32_t dword ) {
  for ( uint32_t i = 0; i < 32; i++ ) {
    if ( 1 & dword ) { return i; }
    dword = dword >> 1;
  }
  return (uint32_t)-1;
}

unsigned char* apg_bmp_read( const char* filename, int* w, int* h, unsigned int* n_chans ) {
  if ( !filename || !w || !h || !n_chans ) { return NULL; }

  // read in the whole file into memory first - much faster than parsing on-the-fly
  _entire_file_t record;
  if ( !_read_entire_file( filename, &record ) ) { return NULL; }
  if ( record.sz < _BMP_MIN_HDR_SZ ) {
    free( record.data );
    return NULL;
  }

  // grab and validate the first, file, header
  _bmp_file_header_t* file_hdr_ptr = (_bmp_file_header_t*)record.data;
  if ( !_validate_file_hdr( file_hdr_ptr, record.sz ) ) {
    free( record.data );
    return NULL;
  }

  // grad and validate the second, DIB, header
  _bmp_dib_BITMAPINFOHEADER_t* dib_hdr_ptr = (_bmp_dib_BITMAPINFOHEADER_t*)( (uint8_t*)record.data + _BMP_FILE_HDR_SZ );
  if ( !_validate_dib_hdr( dib_hdr_ptr, record.sz ) ) {
    free( record.data );
    return NULL;
  }

  // bitmaps can have negative dims to indicate the image should be flipped
  uint32_t width = *w = abs( dib_hdr_ptr->w );
  uint32_t height = *h = abs( dib_hdr_ptr->h );

  // TODO(Anton) flip image memory at the end if this is true. because doing it per row was making me write bugs.
  // bool vertically_flip = dib_hdr_ptr->h > 0 ? false : true;

  // channel count and palette are not well defined in the header so we make a good guess here
  uint32_t n_dst_chans = 3, n_src_chans = 3;
  bool has_palette = false;
  switch ( dib_hdr_ptr->bpp ) {
  case 32: n_dst_chans = n_src_chans = 4; break; // technically can be RGB but not supported
  case 24: n_dst_chans = n_src_chans = 3; break; // technically can be RGBA but not supported
  case 8:                                        // seems to always use a BGR0 palette, even for greyscale
    n_dst_chans = 3;
    has_palette = true;
    n_src_chans = 1;
    break;
  case 4: // always has a palette - needed for a MS-saved BMP
    n_dst_chans = 3;
    has_palette = true;
    n_src_chans = 1;
    break;
  case 1: // 1-bpp means the palette has 3 colour channels with 2 colours i.e. monochrome but not always black & white
    n_dst_chans = 3;
    has_palette = true;
    n_src_chans = 1;
    break;
  default: // this includes 2bpp and 16bpp
    free( record.data );
    return NULL;
  } // endswitch
  *n_chans = n_dst_chans;
  // NOTE(Anton) some image formats are not allowed a palette - could check for a bad header spec here also
  if ( dib_hdr_ptr->n_colours_in_palette > 0 ) { has_palette = true; }

#ifdef APG_BMP_DEBUG_OUTPUT
  printf( "apg_bmp_debug: reading image\n|-filename `%s`\n|-dims %ux%u pixels\n|-bpp %u\n|-n_src_chans %u\n|-n_dst_chans %u\n", filename, *w, *h,
    dib_hdr_ptr->bpp, n_src_chans, n_dst_chans );
#endif

  uint32_t palette_offset = _BMP_FILE_HDR_SZ + dib_hdr_ptr->this_header_sz;
  bool has_bitmasks       = false;
  if ( BI_BITFIELDS == dib_hdr_ptr->compression_method || BI_ALPHABITFIELDS == dib_hdr_ptr->compression_method ) {
    has_bitmasks = true;
    palette_offset += 12;
  }
  if ( palette_offset > record.sz ) {
    free( record.data );
    return NULL;
  }

  // work out if any padding how much to skip at end of each row
  uint32_t unpadded_row_sz = width * n_src_chans;
  // bit-encoded palette indices have different padding properties
  if ( 4 == dib_hdr_ptr->bpp ) {
    unpadded_row_sz = width % 2 > 0 ? width / 2 + 1 : width / 2; // find how many whole bytes required for this bit width
  }
  if ( 1 == dib_hdr_ptr->bpp ) {
    unpadded_row_sz = width % 8 > 0 ? width / 8 + 1 : width / 8; // find how many whole bytes required for this bit width
  }
  uint32_t row_padding_sz = 0 == unpadded_row_sz % 4 ? 0 : 4 - ( unpadded_row_sz % 4 ); // NOTE(Anton) didn't expect operator precedence of - over %

  // another file size integrity check: partially validate source image data size
  // 'image_data_offset' is by row padded to 4 bytes and is either colour data or palette indices.
  if ( file_hdr_ptr->image_data_offset + ( unpadded_row_sz + row_padding_sz ) * height > record.sz ) {
    free( record.data );
    return NULL;
  }

  // find which bit number each colour channel starts at, so we can separate colours out
  uint32_t bitshift_rgba[4] = {0, 0, 0, 0}; // NOTE(Anton) noticed this was int and not uint32_t so changed it. 17 Mar 2020
  uint32_t bitmask_a        = 0;
  if ( has_bitmasks ) {
    bitmask_a        = ~( dib_hdr_ptr->bitmask_r | dib_hdr_ptr->bitmask_g | dib_hdr_ptr->bitmask_b );
    bitshift_rgba[0] = _bitscan( dib_hdr_ptr->bitmask_r );
    bitshift_rgba[1] = _bitscan( dib_hdr_ptr->bitmask_g );
    bitshift_rgba[2] = _bitscan( dib_hdr_ptr->bitmask_b );
    bitshift_rgba[3] = _bitscan( bitmask_a );
  }

  // allocate memory for the output pixels block. cast to size_t in case width and height are both the max of 65536 and n_dst_chans > 1
  unsigned char* dst_img_ptr = malloc( (size_t)width * (size_t)height * (size_t)n_dst_chans );
  if ( !dst_img_ptr ) {
    free( record.data );
    return NULL;
  }

  uint8_t* palette_data_ptr = (uint8_t*)record.data + palette_offset;
  uint8_t* src_img_ptr      = (uint8_t*)record.data + file_hdr_ptr->image_data_offset;
  size_t dst_stride_sz      = width * n_dst_chans;

  //   == 32-bpp -> 32-bit RGBA. == 32-bit and 16-bit require bitmasks
  if ( 32 == dib_hdr_ptr->bpp ) {
    // check source image has enough data in it to read from
    if ( (size_t)file_hdr_ptr->image_data_offset + (size_t)height * (size_t)width * (size_t)n_src_chans > record.sz ) {
      free( record.data );
      free( dst_img_ptr );
      return NULL;
    }
    size_t src_byte_idx = 0;
    for ( uint32_t r = 0; r < height; r++ ) {
      size_t dst_pixels_idx = r * dst_stride_sz;
      for ( uint32_t c = 0; c < width; c++ ) {
        uint32_t pixel;
        memcpy( &pixel, &src_img_ptr[src_byte_idx], 4 );
        // NOTE(Anton) the below assumes 32-bits is always RGBA 1 byte per channel. 10,10,10 RGB exists though and isn't handled.
        dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & dib_hdr_ptr->bitmask_r ) >> bitshift_rgba[0] );
        dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & dib_hdr_ptr->bitmask_g ) >> bitshift_rgba[1] );
        dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & dib_hdr_ptr->bitmask_b ) >> bitshift_rgba[2] );
        dst_img_ptr[dst_pixels_idx++] = ( uint8_t )( ( pixel & bitmask_a ) >> bitshift_rgba[3] );
        src_byte_idx += 4;
      }
      src_byte_idx += row_padding_sz;
    }

    // == 8-bpp -> 24-bit RGB ==
  } else if ( 8 == dib_hdr_ptr->bpp && has_palette ) {
    // validate indices (body of image data) fits in file
    if ( file_hdr_ptr->image_data_offset + height * width > record.sz ) {
      free( record.data );
      free( dst_img_ptr );
      return NULL;
    }
    size_t src_byte_idx = 0;
    for ( uint32_t r = 0; r < height; r++ ) {
      size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz;
      for ( uint32_t c = 0; c < width; c++ ) {
        // "most palettes are 4 bytes in RGB0 order but 3 for..." - it was actually BRG0 in old images -- Anton
        uint8_t index = src_img_ptr[src_byte_idx]; // 8-bit index value per pixel

        if ( palette_offset + index * 4 + 2 >= record.sz ) {
          free( record.data );
          return dst_img_ptr;
        }
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[index * 4 + 2];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[index * 4 + 1];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[index * 4 + 0];
        src_byte_idx++;
      }
      src_byte_idx += row_padding_sz;
    }

    // == 4-bpp (16-colour) -> 24-bit RGB ==
  } else if ( 4 == dib_hdr_ptr->bpp && has_palette ) {
    size_t src_byte_idx = 0;
    for ( uint32_t r = 0; r < height; r++ ) {
      size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz;
      for ( uint32_t c = 0; c < width; c++ ) {
        if ( file_hdr_ptr->image_data_offset + src_byte_idx > record.sz ) {
          free( record.data );
          free( dst_img_ptr );
          return NULL;
        }
        // handle 2 pixels at a time
        uint8_t pixel_duo = src_img_ptr[src_byte_idx];
        uint8_t a_index   = ( 0xFF & pixel_duo ) >> 4;
        uint8_t b_index   = 0xF & pixel_duo;

        if ( palette_offset + a_index * 4 + 2 >= record.sz ) { // invalid src image
          free( record.data );
          return dst_img_ptr;
        }
        if ( dst_pixels_idx + 3 > width * height * n_dst_chans ) { // done
          free( record.data );
          return dst_img_ptr;
        }
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[a_index * 4 + 2];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[a_index * 4 + 1];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[a_index * 4 + 0];
        if ( ++c >= width ) { // advance a column
          c = 0;
          r++;
          if ( r >= height ) { // done. no need to get second pixel. eg a 1x1 pixel image.
            free( record.data );
            return dst_img_ptr;
          }
          dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz;
        }

        if ( palette_offset + b_index * 4 + 2 >= record.sz ) { // invalid src image
          free( record.data );
          return dst_img_ptr;
        }
        if ( dst_pixels_idx + 3 > width * height * n_dst_chans ) { // done. probably redundant check since checking r >= height.
          free( record.data );
          return dst_img_ptr;
        }
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[b_index * 4 + 2];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[b_index * 4 + 1];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[b_index * 4 + 0];
        src_byte_idx++;
      }
      src_byte_idx += row_padding_sz;
    }

    // == 1-bpp -> 24-bit RGB ==
  } else if ( 1 == dib_hdr_ptr->bpp && has_palette ) {
    /* encoding method for monochrome is not well documented.
    a 2x2 pixel image is stored as 4 1-bit palette indexes
    the palette is stored as any 2 RGB0 colours (not necessarily B&W)
    so for an image with indexes like so:
    1 1
    0 1
    it is bit-encoded as follows, starting at MSB:
    01000000 00000000 00000000 00000000 (first byte val  64)
    11000000 00000000 00000000 00000000 (first byte val 192)
    data is still split by row and each row padded to 4 byte multiples
     */
    size_t src_byte_idx = 0;
    for ( uint32_t r = 0; r < height; r++ ) {
      uint8_t bit_idx       = 0; // used in monochrome
      size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz;
      for ( uint32_t c = 0; c < width; c++ ) {
        if ( 8 == bit_idx ) { // start reading from the next byte
          src_byte_idx++;
          bit_idx = 0;
        }
        if ( file_hdr_ptr->image_data_offset + src_byte_idx > record.sz ) {
          free( record.data );
          return dst_img_ptr;
        }
        uint8_t pixel_oct   = src_img_ptr[src_byte_idx];
        uint8_t bit         = 128 >> bit_idx;
        uint8_t masked      = pixel_oct & bit;
        uint8_t palette_idx = masked > 0 ? 1 : 0;

        if ( palette_offset + palette_idx * 4 + 2 >= record.sz ) {
          free( record.data );
          return dst_img_ptr;
        }
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[palette_idx * 4 + 2];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[palette_idx * 4 + 1];
        dst_img_ptr[dst_pixels_idx++] = palette_data_ptr[palette_idx * 4 + 0];
        bit_idx++;
      }
      src_byte_idx += ( row_padding_sz + 1 ); // 1bpp is special here
    }

    // == 24-bpp -> 24-bit RGB == (but also should handle some other n_chans cases)
  } else {
    // NOTE(Anton) this only supports 1 byte per channel
    if ( file_hdr_ptr->image_data_offset + height * width * n_dst_chans > record.sz ) {
      free( record.data );
      free( dst_img_ptr );
      return NULL;
    }
    size_t src_byte_idx = 0;
    for ( uint32_t r = 0; r < height; r++ ) {
      size_t dst_pixels_idx = ( height - 1 - r ) * dst_stride_sz;
      for ( uint32_t c = 0; c < width; c++ ) {
        // re-orders from BGR to RGB
        if ( n_dst_chans > 3 ) { dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx + 3]; }
        if ( n_dst_chans > 2 ) { dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx + 2]; }
        if ( n_dst_chans > 1 ) { dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx + 1]; }
        dst_img_ptr[dst_pixels_idx++] = src_img_ptr[src_byte_idx];
        src_byte_idx += n_src_chans;
      }
      src_byte_idx += row_padding_sz;
    }
  } // endif bpp

  free( record.data );
  return dst_img_ptr;
}

void apg_bmp_free( unsigned char* pixels_ptr ) {
  if ( !pixels_ptr ) { return; }
  free( pixels_ptr );
}

unsigned int apg_bmp_write( const char* filename, unsigned char* pixels_ptr, int w, int h, unsigned int n_chans ) {
  if ( !filename || !pixels_ptr ) { return 0; }
  if ( 0 == w || 0 == h ) { return 0; }
  if ( labs( w ) > _BMP_MAX_DIMS || labs( h ) > _BMP_MAX_DIMS ) { return 0; }
  if ( n_chans != 3 && n_chans != 4 ) { return 0; }

  uint32_t height = labs( h );
  uint32_t width  = labs( w );
  // work out if any padding how much to skip at end of each row
  const size_t unpadded_row_sz      = width * n_chans;
  const size_t row_padding_sz       = 0 == unpadded_row_sz % 4 ? 0 : 4 - unpadded_row_sz % 4;
  const size_t row_sz               = unpadded_row_sz + row_padding_sz;
  const size_t dst_pixels_padded_sz = row_sz * height;

  const size_t dib_hdr_sz = sizeof( _bmp_dib_BITMAPINFOHEADER_t );
  _bmp_file_header_t file_hdr;
  {
    file_hdr.file_type[0]      = 'B';
    file_hdr.file_type[1]      = 'M';
    file_hdr.file_sz           = _BMP_FILE_HDR_SZ + (uint32_t)dib_hdr_sz + (uint32_t)dst_pixels_padded_sz;
    file_hdr.reserved1         = 0;
    file_hdr.reserved2         = 0;
    file_hdr.image_data_offset = _BMP_FILE_HDR_SZ + (uint32_t)dib_hdr_sz;
  }
  _bmp_dib_BITMAPINFOHEADER_t dib_hdr;
  {
    dib_hdr.this_header_sz         = _BMP_MIN_DIB_HDR_SZ; // NOTE: must be 40 and not include the bitmask memory in size here
    dib_hdr.w                      = w;
    dib_hdr.h                      = h;
    dib_hdr.n_planes               = 1;
    dib_hdr.bpp                    = 3 == n_chans ? 24 : 32;
    dib_hdr.compression_method     = 3 == n_chans ? BI_RGB : BI_BITFIELDS;
    dib_hdr.image_uncompressed_sz  = 0;
    dib_hdr.horiz_pixels_per_meter = 0;
    dib_hdr.vert_pixels_per_meter  = 0;
    dib_hdr.n_colours_in_palette   = 0;
    dib_hdr.n_important_colours    = 0;
    // big-endian masks. only used in BI_BITFIELDS and BI_ALPHABITFIELDS ( 16 and 32-bit images )
    // important note: GIMP stores BMP data in this array order for 32-bit: [A][B][G][R]
    dib_hdr.bitmask_r = 0xFF000000;
    dib_hdr.bitmask_g = 0x00FF0000;
    dib_hdr.bitmask_b = 0x0000FF00;
  }

  uint8_t* dst_pixels_ptr = malloc( dst_pixels_padded_sz );
  if ( !dst_pixels_ptr ) { return 0; }
  {
    size_t dst_byte_idx = 0;
    uint8_t padding[4]  = {0, 0, 0, 0};
    uint8_t rgba[4]     = {0, 0, 0, 0};
    uint8_t bgra[4]     = {0, 0, 0, 0};

    for ( uint32_t row = 0; row < height; row++ ) {
      size_t src_byte_idx = ( height - 1 - row ) * n_chans * width;
      for ( uint32_t col = 0; col < width; col++ ) {
        for ( uint32_t chan = 0; chan < n_chans; chan++ ) { rgba[chan] = pixels_ptr[src_byte_idx++]; }
        if ( 3 == n_chans ) {
          bgra[0] = rgba[2];
          bgra[1] = rgba[1];
          bgra[2] = rgba[0];
        } else {
          /* NOTE(Anton) RGBA with alpha channel would be better supported with an extended DIB header */
          bgra[0] = rgba[3];
          bgra[1] = rgba[2];
          bgra[2] = rgba[1];
          bgra[3] = rgba[0]; // alpha
        }
        memcpy( &dst_pixels_ptr[dst_byte_idx], bgra, n_chans );
        dst_byte_idx += (size_t)n_chans;
      } // endfor col
      if ( row_padding_sz > 0 ) {
        memcpy( &dst_pixels_ptr[dst_byte_idx], padding, row_padding_sz );
        dst_byte_idx += row_padding_sz;
      }
    } // endfor row
  }
  {
    FILE* fp = fopen( filename, "wb" );
    if ( !fp ) {
      free( dst_pixels_ptr );
      return 0;
    }
    if ( 1 != fwrite( &file_hdr, _BMP_FILE_HDR_SZ, 1, fp ) ) {
      free( dst_pixels_ptr );
      fclose( fp );
      return 0;
    }
    if ( 1 != fwrite( &dib_hdr, dib_hdr_sz, 1, fp ) ) {
      free( dst_pixels_ptr );
      fclose( fp );
      return 0;
    }
    if ( 1 != fwrite( dst_pixels_ptr, dst_pixels_padded_sz, 1, fp ) ) {
      free( dst_pixels_ptr );
      fclose( fp );
      return 0;
    }
    fclose( fp );
  }
  free( dst_pixels_ptr );

  return 1;
}
