/*
 * wrbmp.c
 *
 * This file was part of the Independent JPEG Group's software:
 * Copyright (C) 1994-1996, Thomas G. Lane.
 * libjpeg-turbo Modifications:
 * Copyright (C) 2013, Linaro Limited.
 * Copyright (C) 2014-2015, 2017, 2019, 2022, D. R. Commander.
 * For conditions of distribution and use, see the accompanying README.ijg
 * file.
 *
 * This file contains routines to write output images in Microsoft "BMP"
 * format (MS Windows 3.x and OS/2 1.x flavors).
 * Either 8-bit colormapped or 24-bit full-color format can be written.
 * No compression is supported.
 *
 * These routines may need modification for non-Unix environments or
 * specialized applications.  As they stand, they assume output to
 * an ordinary stdio stream.
 *
 * This code contributed by James Arthur Boucher.
 */

#include "cmyk.h"
#include "cdjpeg.h"             /* Common decls for cjpeg/djpeg applications */
#include "jconfigint.h"

#ifdef BMP_SUPPORTED


/*
 * To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
 * This is not yet implemented.
 */

#if BITS_IN_JSAMPLE != 8
  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
#endif

/*
 * Since BMP stores scanlines bottom-to-top, we have to invert the image
 * from JPEG's top-to-bottom order.  To do this, we save the outgoing data
 * in a virtual array during put_pixel_row calls, then actually emit the
 * BMP file during finish_output.  The virtual array contains one JSAMPLE per
 * pixel if the output is grayscale or colormapped, three if it is full color.
 */

/* Private version of data destination object */

typedef struct {
  struct djpeg_dest_struct pub; /* public fields */

  boolean is_os2;               /* saves the OS2 format request flag */

  jvirt_sarray_ptr whole_image; /* needed to reverse row order */
  JDIMENSION data_width;        /* JSAMPLEs per row */
  JDIMENSION row_width;         /* physical width of one row in the BMP file */
  int pad_bytes;                /* number of padding bytes needed per row */
  JDIMENSION cur_output_row;    /* next row# to write to virtual array */

  boolean use_inversion_array;  /* TRUE = buffer the whole image, which is
                                   stored to disk in bottom-up order, and
                                   receive rows from the calling program in
                                   top-down order

                                   FALSE = the calling program will maintain
                                   its own image buffer and write the rows in
                                   bottom-up order */

  JSAMPLE *iobuffer;            /* I/O buffer (used to buffer a single row to
                                   disk if use_inversion_array == FALSE) */
} bmp_dest_struct;

typedef bmp_dest_struct *bmp_dest_ptr;


/* Forward declarations */
LOCAL(void) write_colormap(j_decompress_ptr cinfo, bmp_dest_ptr dest,
                           int map_colors, int map_entry_size);


static INLINE boolean is_big_endian(void)
{
  int test_value = 1;
  if (*(char *)&test_value != 1)
    return TRUE;
  return FALSE;
}


/*
 * Write some pixel data.
 * In this module rows_supplied will always be 1.
 */

METHODDEF(void)
put_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
               JDIMENSION rows_supplied)
/* This version is for writing 24-bit pixels */
{
  bmp_dest_ptr dest = (bmp_dest_ptr)dinfo;
  JSAMPARRAY image_ptr;
  register JSAMPROW inptr, outptr;
  register JDIMENSION col;
  int pad;

  if (dest->use_inversion_array) {
    /* Access next row in virtual array */
    image_ptr = (*cinfo->mem->access_virt_sarray)
      ((j_common_ptr)cinfo, dest->whole_image,
       dest->cur_output_row, (JDIMENSION)1, TRUE);
    dest->cur_output_row++;
    outptr = image_ptr[0];
  } else {
    outptr = dest->iobuffer;
  }

  /* Transfer data.  Note destination values must be in BGR order
   * (even though Microsoft's own documents say the opposite).
   */
  inptr = dest->pub.buffer[0];

  if (cinfo->out_color_space == JCS_EXT_BGR) {
    memcpy(outptr, inptr, dest->row_width);
    outptr += cinfo->output_width * 3;
  } else if (cinfo->out_color_space == JCS_RGB565) {
    boolean big_endian = is_big_endian();
    unsigned short *inptr2 = (unsigned short *)inptr;
    for (col = cinfo->output_width; col > 0; col--) {
      if (big_endian) {
        outptr[0] = (*inptr2 >> 5) & 0xF8;
        outptr[1] = ((*inptr2 << 5) & 0xE0) | ((*inptr2 >> 11) & 0x1C);
        outptr[2] = *inptr2 & 0xF8;
      } else {
        outptr[0] = (*inptr2 << 3) & 0xF8;
        outptr[1] = (*inptr2 >> 3) & 0xFC;
        outptr[2] = (*inptr2 >> 8) & 0xF8;
      }
      outptr += 3;
      inptr2++;
    }
  } else if (cinfo->out_color_space == JCS_CMYK) {
    for (col = cinfo->output_width; col > 0; col--) {
      JSAMPLE c = *inptr++, m = *inptr++, y = *inptr++, k = *inptr++;
      cmyk_to_rgb(c, m, y, k, outptr + 2, outptr + 1, outptr);
      outptr += 3;
    }
  } else {
    register int rindex = rgb_red[cinfo->out_color_space];
    register int gindex = rgb_green[cinfo->out_color_space];
    register int bindex = rgb_blue[cinfo->out_color_space];
    register int ps = rgb_pixelsize[cinfo->out_color_space];

    for (col = cinfo->output_width; col > 0; col--) {
      outptr[0] = inptr[bindex];
      outptr[1] = inptr[gindex];
      outptr[2] = inptr[rindex];
      outptr += 3;  inptr += ps;
    }
  }

  /* Zero out the pad bytes. */
  pad = dest->pad_bytes;
  while (--pad >= 0)
    *outptr++ = 0;

  if (!dest->use_inversion_array)
    fwrite(dest->iobuffer, 1, dest->row_width, dest->pub.output_file);
}

METHODDEF(void)
put_gray_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
              JDIMENSION rows_supplied)
/* This version is for grayscale OR quantized color output */
{
  bmp_dest_ptr dest = (bmp_dest_ptr)dinfo;
  JSAMPARRAY image_ptr;
  register JSAMPROW inptr, outptr;
  int pad;

  if (dest->use_inversion_array) {
    /* Access next row in virtual array */
    image_ptr = (*cinfo->mem->access_virt_sarray)
      ((j_common_ptr)cinfo, dest->whole_image,
       dest->cur_output_row, (JDIMENSION)1, TRUE);
    dest->cur_output_row++;
    outptr = image_ptr[0];
  } else {
    outptr = dest->iobuffer;
  }

  /* Transfer data. */
  inptr = dest->pub.buffer[0];
  memcpy(outptr, inptr, cinfo->output_width);
  outptr += cinfo->output_width;

  /* Zero out the pad bytes. */
  pad = dest->pad_bytes;
  while (--pad >= 0)
    *outptr++ = 0;

  if (!dest->use_inversion_array)
    fwrite(dest->iobuffer, 1, dest->row_width, dest->pub.output_file);
}


/*
 * Finish up at the end of the file.
 *
 * Here is where we really output the BMP file.
 *
 * First, routines to write the Windows and OS/2 variants of the file header.
 */

LOCAL(void)
write_bmp_header(j_decompress_ptr cinfo, bmp_dest_ptr dest)
/* Write a Windows-style BMP file header, including colormap if needed */
{
  char bmpfileheader[14];
  char bmpinfoheader[40];

#define PUT_2B(array, offset, value) \
  (array[offset] = (char)((value) & 0xFF), \
   array[offset + 1] = (char)(((value) >> 8) & 0xFF))
#define PUT_4B(array, offset, value) \
  (array[offset] = (char)((value) & 0xFF), \
   array[offset + 1] = (char)(((value) >> 8) & 0xFF), \
   array[offset + 2] = (char)(((value) >> 16) & 0xFF), \
   array[offset + 3] = (char)(((value) >> 24) & 0xFF))

  long headersize, bfSize;
  int bits_per_pixel, cmap_entries;

  /* Compute colormap size and total file size */
  if (IsExtRGB(cinfo->out_color_space)) {
    if (cinfo->quantize_colors) {
      /* Colormapped RGB */
      bits_per_pixel = 8;
      cmap_entries = 256;
    } else {
      /* Unquantized, full color RGB */
      bits_per_pixel = 24;
      cmap_entries = 0;
    }
  } else if (cinfo->out_color_space == JCS_RGB565 ||
             cinfo->out_color_space == JCS_CMYK) {
    bits_per_pixel = 24;
    cmap_entries   = 0;
  } else {
    /* Grayscale output.  We need to fake a 256-entry colormap. */
    bits_per_pixel = 8;
    cmap_entries = 256;
  }
  /* File size */
  headersize = 14 + 40 + cmap_entries * 4; /* Header and colormap */
  bfSize = headersize + (long)dest->row_width * (long)cinfo->output_height;

  /* Set unused fields of header to 0 */
  memset(bmpfileheader, 0, sizeof(bmpfileheader));
  memset(bmpinfoheader, 0, sizeof(bmpinfoheader));

  /* Fill the file header */
  bmpfileheader[0] = 0x42;      /* first 2 bytes are ASCII 'B', 'M' */
  bmpfileheader[1] = 0x4D;
  PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */
  /* we leave bfReserved1 & bfReserved2 = 0 */
  PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */

  /* Fill the info header (Microsoft calls this a BITMAPINFOHEADER) */
  PUT_2B(bmpinfoheader, 0, 40); /* biSize */
  PUT_4B(bmpinfoheader, 4, cinfo->output_width); /* biWidth */
  PUT_4B(bmpinfoheader, 8, cinfo->output_height); /* biHeight */
  PUT_2B(bmpinfoheader, 12, 1); /* biPlanes - must be 1 */
  PUT_2B(bmpinfoheader, 14, bits_per_pixel); /* biBitCount */
  /* we leave biCompression = 0, for none */
  /* we leave biSizeImage = 0; this is correct for uncompressed data */
  if (cinfo->density_unit == 2) { /* if have density in dots/cm, then */
    PUT_4B(bmpinfoheader, 24, (long)(cinfo->X_density * 100)); /* XPels/M */
    PUT_4B(bmpinfoheader, 28, (long)(cinfo->Y_density * 100)); /* XPels/M */
  }
  PUT_2B(bmpinfoheader, 32, cmap_entries); /* biClrUsed */
  /* we leave biClrImportant = 0 */

  if (fwrite(bmpfileheader, 1, 14, dest->pub.output_file) != (size_t)14)
    ERREXIT(cinfo, JERR_FILE_WRITE);
  if (fwrite(bmpinfoheader, 1, 40, dest->pub.output_file) != (size_t)40)
    ERREXIT(cinfo, JERR_FILE_WRITE);

  if (cmap_entries > 0)
    write_colormap(cinfo, dest, cmap_entries, 4);
}


LOCAL(void)
write_os2_header(j_decompress_ptr cinfo, bmp_dest_ptr dest)
/* Write an OS2-style BMP file header, including colormap if needed */
{
  char bmpfileheader[14];
  char bmpcoreheader[12];
  long headersize, bfSize;
  int bits_per_pixel, cmap_entries;

  /* Compute colormap size and total file size */
  if (IsExtRGB(cinfo->out_color_space)) {
    if (cinfo->quantize_colors) {
      /* Colormapped RGB */
      bits_per_pixel = 8;
      cmap_entries = 256;
    } else {
      /* Unquantized, full color RGB */
      bits_per_pixel = 24;
      cmap_entries = 0;
    }
  } else if (cinfo->out_color_space == JCS_RGB565 ||
             cinfo->out_color_space == JCS_CMYK) {
    bits_per_pixel = 24;
    cmap_entries   = 0;
  } else {
    /* Grayscale output.  We need to fake a 256-entry colormap. */
    bits_per_pixel = 8;
    cmap_entries = 256;
  }
  /* File size */
  headersize = 14 + 12 + cmap_entries * 3; /* Header and colormap */
  bfSize = headersize + (long)dest->row_width * (long)cinfo->output_height;

  /* Set unused fields of header to 0 */
  memset(bmpfileheader, 0, sizeof(bmpfileheader));
  memset(bmpcoreheader, 0, sizeof(bmpcoreheader));

  /* Fill the file header */
  bmpfileheader[0] = 0x42;      /* first 2 bytes are ASCII 'B', 'M' */
  bmpfileheader[1] = 0x4D;
  PUT_4B(bmpfileheader, 2, bfSize); /* bfSize */
  /* we leave bfReserved1 & bfReserved2 = 0 */
  PUT_4B(bmpfileheader, 10, headersize); /* bfOffBits */

  /* Fill the info header (Microsoft calls this a BITMAPCOREHEADER) */
  PUT_2B(bmpcoreheader, 0, 12); /* bcSize */
  PUT_2B(bmpcoreheader, 4, cinfo->output_width); /* bcWidth */
  PUT_2B(bmpcoreheader, 6, cinfo->output_height); /* bcHeight */
  PUT_2B(bmpcoreheader, 8, 1);  /* bcPlanes - must be 1 */
  PUT_2B(bmpcoreheader, 10, bits_per_pixel); /* bcBitCount */

  if (fwrite(bmpfileheader, 1, 14, dest->pub.output_file) != (size_t)14)
    ERREXIT(cinfo, JERR_FILE_WRITE);
  if (fwrite(bmpcoreheader, 1, 12, dest->pub.output_file) != (size_t)12)
    ERREXIT(cinfo, JERR_FILE_WRITE);

  if (cmap_entries > 0)
    write_colormap(cinfo, dest, cmap_entries, 3);
}


/*
 * Write the colormap.
 * Windows uses BGR0 map entries; OS/2 uses BGR entries.
 */

LOCAL(void)
write_colormap(j_decompress_ptr cinfo, bmp_dest_ptr dest, int map_colors,
               int map_entry_size)
{
  JSAMPARRAY colormap = cinfo->colormap;
  int num_colors = cinfo->actual_number_of_colors;
  FILE *outfile = dest->pub.output_file;
  int i;

  if (colormap != NULL) {
    if (cinfo->out_color_components == 3) {
      /* Normal case with RGB colormap */
      for (i = 0; i < num_colors; i++) {
        putc(colormap[2][i], outfile);
        putc(colormap[1][i], outfile);
        putc(colormap[0][i], outfile);
        if (map_entry_size == 4)
          putc(0, outfile);
      }
    } else {
      /* Grayscale colormap (only happens with grayscale quantization) */
      for (i = 0; i < num_colors; i++) {
        putc(colormap[0][i], outfile);
        putc(colormap[0][i], outfile);
        putc(colormap[0][i], outfile);
        if (map_entry_size == 4)
          putc(0, outfile);
      }
    }
  } else {
    /* If no colormap, must be grayscale data.  Generate a linear "map". */
    for (i = 0; i < 256; i++) {
      putc(i, outfile);
      putc(i, outfile);
      putc(i, outfile);
      if (map_entry_size == 4)
        putc(0, outfile);
    }
  }
  /* Pad colormap with zeros to ensure specified number of colormap entries */
  if (i > map_colors)
    ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i);
  for (; i < map_colors; i++) {
    putc(0, outfile);
    putc(0, outfile);
    putc(0, outfile);
    if (map_entry_size == 4)
      putc(0, outfile);
  }
}


/*
 * Startup: write the file header unless the inversion array is being used.
 */

METHODDEF(void)
start_output_bmp(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
  bmp_dest_ptr dest = (bmp_dest_ptr)dinfo;

  if (!dest->use_inversion_array) {
    /* Write the header and colormap */
    if (dest->is_os2)
      write_os2_header(cinfo, dest);
    else
      write_bmp_header(cinfo, dest);
  }
}


METHODDEF(void)
finish_output_bmp(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
  bmp_dest_ptr dest = (bmp_dest_ptr)dinfo;
  register FILE *outfile = dest->pub.output_file;
  JSAMPARRAY image_ptr;
  register JSAMPROW data_ptr;
  JDIMENSION row;
  cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;

  if (dest->use_inversion_array) {
    /* Write the header and colormap */
    if (dest->is_os2)
      write_os2_header(cinfo, dest);
    else
      write_bmp_header(cinfo, dest);

    /* Write the file body from our virtual array */
    for (row = cinfo->output_height; row > 0; row--) {
      if (progress != NULL) {
        progress->pub.pass_counter = (long)(cinfo->output_height - row);
        progress->pub.pass_limit = (long)cinfo->output_height;
        (*progress->pub.progress_monitor) ((j_common_ptr)cinfo);
      }
      image_ptr = (*cinfo->mem->access_virt_sarray)
        ((j_common_ptr)cinfo, dest->whole_image, row - 1, (JDIMENSION)1,
         FALSE);
      data_ptr = image_ptr[0];
      fwrite(data_ptr, 1, dest->row_width, outfile);
    }
    if (progress != NULL)
      progress->completed_extra_passes++;
  }

  /* Make sure we wrote the output file OK */
  fflush(outfile);
  if (ferror(outfile))
    ERREXIT(cinfo, JERR_FILE_WRITE);
}


/*
 * The module selection routine for BMP format output.
 */

GLOBAL(djpeg_dest_ptr)
jinit_write_bmp(j_decompress_ptr cinfo, boolean is_os2,
                boolean use_inversion_array)
{
  bmp_dest_ptr dest;
  JDIMENSION row_width;

  /* Create module interface object, fill in method pointers */
  dest = (bmp_dest_ptr)
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
                                sizeof(bmp_dest_struct));
  dest->pub.start_output = start_output_bmp;
  dest->pub.finish_output = finish_output_bmp;
  dest->pub.calc_buffer_dimensions = NULL;
  dest->is_os2 = is_os2;

  if (cinfo->out_color_space == JCS_GRAYSCALE) {
    dest->pub.put_pixel_rows = put_gray_rows;
  } else if (IsExtRGB(cinfo->out_color_space)) {
    if (cinfo->quantize_colors)
      dest->pub.put_pixel_rows = put_gray_rows;
    else
      dest->pub.put_pixel_rows = put_pixel_rows;
  } else if (!cinfo->quantize_colors &&
             (cinfo->out_color_space == JCS_RGB565 ||
              cinfo->out_color_space == JCS_CMYK)) {
    dest->pub.put_pixel_rows = put_pixel_rows;
  } else {
    ERREXIT(cinfo, JERR_BMP_COLORSPACE);
  }

  /* Calculate output image dimensions so we can allocate space */
  jpeg_calc_output_dimensions(cinfo);

  /* Determine width of rows in the BMP file (padded to 4-byte boundary). */
  if (cinfo->out_color_space == JCS_RGB565) {
    row_width = cinfo->output_width * 2;
    dest->row_width = dest->data_width = cinfo->output_width * 3;
    while ((row_width & 3) != 0) row_width++;
  } else if (!cinfo->quantize_colors &&
             (IsExtRGB(cinfo->out_color_space) ||
              cinfo->out_color_space == JCS_CMYK)) {
    row_width = cinfo->output_width * cinfo->output_components;
    dest->row_width = dest->data_width = cinfo->output_width * 3;
  } else {
    row_width = cinfo->output_width * cinfo->output_components;
    dest->row_width = dest->data_width = row_width;
  }
  while ((dest->row_width & 3) != 0) dest->row_width++;
  dest->pad_bytes = (int)(dest->row_width - dest->data_width);


  if (use_inversion_array) {
    /* Allocate space for inversion array, prepare for write pass */
    dest->whole_image = (*cinfo->mem->request_virt_sarray)
      ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE,
       dest->row_width, cinfo->output_height, (JDIMENSION)1);
    dest->cur_output_row = 0;
    if (cinfo->progress != NULL) {
      cd_progress_ptr progress = (cd_progress_ptr)cinfo->progress;
      progress->total_extra_passes++; /* count file input as separate pass */
    }
  } else {
    dest->iobuffer = (JSAMPLE *)(*cinfo->mem->alloc_small)
      ((j_common_ptr)cinfo, JPOOL_IMAGE, dest->row_width);
  }
  dest->use_inversion_array = use_inversion_array;

  /* Create decompressor output buffer. */
  dest->pub.buffer = (*cinfo->mem->alloc_sarray)
    ((j_common_ptr)cinfo, JPOOL_IMAGE, row_width, (JDIMENSION)1);
  dest->pub.buffer_height = 1;

  return (djpeg_dest_ptr)dest;
}

#endif /* BMP_SUPPORTED */
