Example #1
0
static void
bmp_write_palette(bmpfile_t *bmp, FILE *fp)
{
  if (bmp->dib.depth == 1 || bmp->dib.depth == 4 || bmp->dib.depth == 8) {
    int i;
    for (i = 0; i < bmp->dib.ncolors; ++i)
      fwrite(&(bmp->colors[i]), sizeof(rgb_pixel_t), 1, fp);
  }
  else if (bmp->dib.depth == 16) { /* the bit masks, not palette */
    uint16_t red_mask = 63488;  /* bits 1-5 */
    uint16_t green_mask = 2016; /* bits 6-11 */
    uint16_t blue_mask = 31;    /* bits 12-16 */
    uint16_t zero_word = 0;

    if (_is_big_endian()) {
      red_mask = UINT16_SWAP_LE_BE_CONSTANT(red_mask);
      green_mask = UINT16_SWAP_LE_BE_CONSTANT(green_mask);
      blue_mask = UINT16_SWAP_LE_BE_CONSTANT(blue_mask);
    }

    fwrite(&red_mask, sizeof(uint16_t), 1, fp);
    fwrite(&zero_word, sizeof(uint16_t), 1, fp);

    fwrite(&green_mask, sizeof(uint16_t), 1, fp);
    fwrite(&zero_word, sizeof(uint16_t), 1, fp);

    fwrite(&blue_mask, sizeof(uint16_t), 1, fp);
    fwrite(&zero_word, sizeof(uint16_t), 1, fp);
  }
}
Example #2
0
void bmp_write_palette(bmp_structp bmp)
{
	if (bmp->dib.depth == 1 || bmp->dib.depth == 4 || bmp->dib.depth == 8)
	{
		bmp->write_fn(bmp, (uint8_t*)bmp->colors,
			sizeof(rgb_pixel_t) * bmp->dib.ncolors);
	}
	else if (bmp->dib.depth == 16)
	{
		/* the bit masks, not palette */
		uint16_t red_mask = 63488;  /* bits 1-5 */
		uint16_t green_mask = 2016; /* bits 6-11 */
		uint16_t blue_mask = 31;    /* bits 12-16 */
		uint16_t zero_word = 0;

		if (_is_big_endian()) {
			red_mask = UINT16_SWAP_LE_BE_CONSTANT(red_mask);
			green_mask = UINT16_SWAP_LE_BE_CONSTANT(green_mask);
			blue_mask = UINT16_SWAP_LE_BE_CONSTANT(blue_mask);
		}

		bmp->write_fn(bmp, (uint8_t*)&red_mask, sizeof(uint16_t));
		bmp->write_fn(bmp, (uint8_t*)&zero_word, sizeof(uint16_t));

		bmp->write_fn(bmp, (uint8_t*)&green_mask, sizeof(uint16_t));
		bmp->write_fn(bmp, (uint8_t*)&zero_word, sizeof(uint16_t));

		bmp->write_fn(bmp, (uint8_t*)&blue_mask, sizeof(uint16_t));
		bmp->write_fn(bmp, (uint8_t*)&zero_word, sizeof(uint16_t));
	}
}
Example #3
0
void bmp_write_header(bmp_structp bmp)
{
	if (_is_big_endian())
		bmp_header_swap_endianess(&bmp->header);

	bmp->write_fn(bmp, (uint8_t*)&bmp->header.magic, sizeof(uint8_t) * 2);
	bmp->write_fn(bmp, (uint8_t*)&bmp->header.filesz, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->header.creator1, sizeof(uint16_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->header.creator2, sizeof(uint16_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->header.offset, sizeof(uint32_t));
}
Example #4
0
static void
bmp_write_header(bmpfile_t *bmp, FILE *fp)
{
  bmp_header_t header = bmp->header;

  if (_is_big_endian()) bmp_header_swap_endianess(&header);

  fwrite(header.magic, sizeof(header.magic), 1, fp);
  fwrite(&(header.filesz), sizeof(uint32_t), 1, fp);
  fwrite(&(header.creator1), sizeof(uint16_t), 1, fp);
  fwrite(&(header.creator2), sizeof(uint16_t), 1, fp);
  fwrite(&(header.offset), sizeof(uint32_t), 1, fp);
}
Example #5
0
void bmp_write_dib(bmp_structp bmp)
{
	if (_is_big_endian())
		bmp_dib_v3_header_swap_endianess(&bmp->dib);

	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.header_sz, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.width, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.height, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.nplanes, sizeof(uint16_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.depth, sizeof(uint16_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.compress_type, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.bmp_bytesz, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.hres, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.vres, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.ncolors, sizeof(uint32_t));
	bmp->write_fn(bmp, (uint8_t*)&bmp->dib.nimpcolors, sizeof(uint32_t));
}
Example #6
0
static void
bmp_write_dib(bmpfile_t *bmp, FILE *fp)
{
  bmp_dib_v3_header_t dib = bmp->dib;

  if (_is_big_endian()) bmp_dib_v3_header_swap_endianess(&dib);

  fwrite(&(dib.header_sz), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.width), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.height), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.nplanes), sizeof(uint16_t), 1, fp);
  fwrite(&(dib.depth), sizeof(uint16_t), 1, fp);
  fwrite(&(dib.compress_type), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.bmp_bytesz), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.hres), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.vres), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.ncolors), sizeof(uint32_t), 1, fp);
  fwrite(&(dib.nimpcolors), sizeof(uint32_t), 1, fp);
}
Example #7
0
void
bmp_write_pixels(bmp_structp bmp, uint32_t offset, uint32_t length)
{
	int index;
	unsigned char *buf;


	if (bmp->dib.depth == 16) {
		uint32_t data_bytes = bmp->dib.width * 2;
		uint32_t padding_bytes = 4 - data_bytes % 4;

		unsigned char zero_byte = 0;

		for (; index = bmp->dib.height * data_bytes; ++index)
		{
			uint16_t red = (uint16_t)(bmp->pixels[index].red / 8);
			uint16_t green = (uint16_t)(bmp->pixels[index].green / 4);
			uint16_t blue = (uint16_t)(bmp->pixels[index].blue / 8);
			uint16_t value = (red << 11) + (green << 5) + blue;

			if (_is_big_endian()) value = UINT16_SWAP_LE_BE_CONSTANT(value);
			bmp->write_fn(bmp, (uint8_t*)&value, sizeof(uint16_t));
		}
	}
	else
	{
		double bytes_per_pixel;
		int bytes_per_line;

		bytes_per_pixel = (bmp->dib.depth * 1.0) / 8.0;
		bytes_per_line = (int)ceil(bytes_per_pixel * bmp->dib.width);
		if (bytes_per_line % 4 != 0)
			bytes_per_line += 4 - bytes_per_line % 4;

		int row;
		buf = (unsigned char*)malloc(bytes_per_line);
		for (row = bmp->dib.height - 1; row >= 0; --row)
		{
			memset(buf, 0, bytes_per_line);

			switch (bmp->dib.depth) {
			case 1:
				bmp_get_row_data_for_1(bmp, buf, bytes_per_line, row);
				break;

			case 4:
				bmp_get_row_data_for_4(bmp, buf, bytes_per_line, row);
				break;

			case 8:
				bmp_get_row_data_for_8(bmp, buf, bytes_per_line, row);
				break;

			case 24:
				bmp_get_row_data_for_24(bmp, buf, bytes_per_line, row);
				break;

			case 32:
				bmp_get_row_data_for_32(bmp, buf, bytes_per_line, row);
				break;
			}

			bmp->write_fn(bmp, buf, bytes_per_line);
		}

		free(buf);
	}
}
Example #8
0
bool
bmp_save(bmpfile_t *bmp, const char *filename)
{
  FILE *fp;
  int row;
  unsigned char *buf;

  /* Create the file */
  if ((fp = fopen(filename, "wb")) == NULL)
    return FALSE;

  /* Write the file */
  bmp_write_header(bmp, fp);
  bmp_write_dib(bmp, fp);
  bmp_write_palette(bmp, fp);

  if (bmp->dib.depth == 16) {
    uint32_t data_bytes = bmp->dib.width * 2;
    uint32_t padding_bytes = 4 - data_bytes % 4;

    for (row = bmp->dib.height - 1; row >= 0; --row) {
      int i;
      unsigned char zero_byte = 0;
      uint32_t write_number = 0;

      for (i = 0; write_number < data_bytes; ++i, write_number += 2) {
	uint16_t red = (uint16_t)(bmp->pixels[i][row].uniColour / 8);
	uint16_t green = (uint16_t)(bmp->pixels[i][row].uniColour / 4);
	uint16_t blue = (uint16_t)(bmp->pixels[i][row].uniColour / 8);
	uint16_t value = (red << 11) + (green << 5) + blue;

	if (_is_big_endian()) value = UINT16_SWAP_LE_BE_CONSTANT(value);
	fwrite(&value, sizeof(uint16_t), 1, fp);
      }

      for (write_number = 0; write_number < padding_bytes; ++write_number)
	fwrite(&zero_byte, 1, 1, fp);
    }
  }
  else {
    double bytes_per_pixel;
    int bytes_per_line;

    bytes_per_pixel = (bmp->dib.depth * 1.0) / 8.0;
    bytes_per_line = (int)ceil(bytes_per_pixel * bmp->dib.width);
    if (bytes_per_line % 4 != 0)
      bytes_per_line += 4 - bytes_per_line % 4;

    buf = malloc(bytes_per_line);

    for (row = bmp->dib.height - 1; row >= 0; --row) {
      memset(buf, 0, bytes_per_line);

      switch (bmp->dib.depth) {
      case 1:
	bmp_get_row_data_for_1(bmp, buf, bytes_per_line, row);
	break;

      case 4:
	bmp_get_row_data_for_4(bmp, buf, bytes_per_line, row);
	break;

      case 8:
	bmp_get_row_data_for_8(bmp, buf, bytes_per_line, row);
	break;

      case 24:
	bmp_get_row_data_for_24(bmp, buf, bytes_per_line, row);
	break;

      case 32:
	bmp_get_row_data_for_32(bmp, buf, bytes_per_line, row);
	break;
      }

      fwrite(buf, bytes_per_line, 1, fp);
    }
    free(buf);
  }

  fclose(fp);

  return TRUE;
}