Tachyon (current)  Current Main Branch
winbmp.c
Go to the documentation of this file.
1 /*
2  * winbmp.c - This file deals with Windows Bitmap image files
3  * (reading/writing)
4  *
5  * (C) Copyright 1994-2022 John E. Stone
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * $Id: winbmp.c,v 1.6 2022/02/18 17:55:28 johns Exp $
9  *
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <math.h>
16 
17 #define TACHYON_INTERNAL 1
18 #include "tachyon.h"
19 #include "util.h"
20 #include "imageio.h" /* error codes etc */
21 #include "winbmp.h" /* the protos for this file */
22 
23 static void write_le_int32(FILE * dfile, int num) {
24  fputc((num ) & 0xFF, dfile);
25  fputc((num >> 8 ) & 0xFF, dfile);
26  fputc((num >> 16) & 0xFF, dfile);
27  fputc((num >> 24) & 0xFF, dfile);
28 }
29 
30 static void write_le_int16(FILE * dfile, int num) {
31  fputc((num ) & 0xFF, dfile);
32  fputc((num >> 8 ) & 0xFF, dfile);
33 }
34 
35 int writebmp(char * filename, int xs, int ys, unsigned char * img) {
36  if (img != NULL) {
37  FILE * dfile;
38 
39  if ((dfile = fopen(filename, "wb")) != NULL) {
40  int i, y; /* loop variables */
41  int imgdataoffset = 14 + 40; /* file header + bitmap header size */
42  int rowlen = xs * 3; /* non-padded row length in pixels */
43  int rowsz = (rowlen + 3) & -4; /* size of one padded row of pixels */
44  int imgdatasize = rowsz * ys; /* size of image data */
45  int filesize = imgdataoffset + imgdatasize;
46  unsigned char * rowbuf = NULL;
47 
48  /* write out bitmap file header (14 bytes) */
49  fputc('B', dfile);
50  fputc('M', dfile);
51  write_le_int32(dfile, filesize);
52  write_le_int16(dfile, 0);
53  write_le_int16(dfile, 0);
54  write_le_int32(dfile, imgdataoffset);
55 
56  /* write out bitmap header (40 bytes) */
57  write_le_int32(dfile, 40); /* size of bitmap header structure */
58  write_le_int32(dfile, xs); /* size of image in x */
59  write_le_int32(dfile, ys); /* size of image in y */
60  write_le_int16(dfile, 1); /* num color planes (only "1" is legal) */
61  write_le_int16(dfile, 24); /* bits per pixel */
62 
63  /* fields added in Win 3.x */
64  write_le_int32(dfile, 0); /* compression used (0 == none) */
65  write_le_int32(dfile, imgdatasize); /* size of bitmap in bytes */
66  write_le_int32(dfile, 11811); /* X pixels per meter (300dpi) */
67  write_le_int32(dfile, 11811); /* Y pixels per meter (300dpi) */
68  write_le_int32(dfile, 0); /* color count (0 for RGB) */
69  write_le_int32(dfile, 0); /* important colors (0 for RGB) */
70 
71  /* write out actual image data */
72  rowbuf = (unsigned char *) malloc(rowsz);
73  if (rowbuf != NULL) {
74  memset(rowbuf, 0, rowsz); /* clear the buffer (and padding) to black */
75 
76  for (y=0; y<ys; y++) {
77  int addr = xs * 3 * y;
78 
79  /* write one row of the image, in reversed RGB -> BGR pixel order */
80  /* padding bytes remain 0's, shouldn't have to re-clear them. */
81  for (i=0; i<rowlen; i+=3) {
82  rowbuf[i ] = img[addr + i + 2]; /* blue */
83  rowbuf[i + 1] = img[addr + i + 1]; /* green */
84  rowbuf[i + 2] = img[addr + i ]; /* red */
85  }
86 
87  fwrite(rowbuf, rowsz, 1, dfile); /* write the whole row of pixels */
88  }
89  free(rowbuf);
90  }
91  fclose(dfile);
92  }
93  }
94 
95  return IMAGENOERR;
96 }
97 
98 
99 
100 
static void write_le_int16(FILE *dfile, int num)
Definition: winbmp.c:30
Tachyon cross-platform timers, special math function wrappers, and RNGs.
static void write_le_int32(FILE *dfile, int num)
Definition: winbmp.c:23
#define IMAGENOERR
no error
Definition: imageio.h:16
int writebmp(char *filename, int xs, int ys, unsigned char *img)
Definition: winbmp.c:35
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...