2 * Windows BMP file functions for OpenGL.
4 * Written by Michael Sweet.
13 * Functions for reading and writing 16- and 32-bit little-endian integers.
16 static unsigned short read_word(FILE *fp);
17 static unsigned int read_dword(FILE *fp);
18 static int read_long(FILE *fp);
21 * 'LoadDIBitmap()' - Load a DIB/BMP file from disk.
23 * Returns a pointer to the bitmap if successful, NULL otherwise...
26 GLubyte * /* O - Bitmap data */
27 LoadDIBitmap(const char *filename, /* I - File to load */
28 BITMAPINFO **info) /* O - Bitmap information */
30 FILE *fp; /* Open file pointer */
31 GLubyte *bits; /* Bitmap pixel bits */
32 GLubyte *ptr; /* Pointer into bitmap */
33 GLubyte temp; /* Temporary variable to swap red and blue */
34 int x, y; /* X and Y position in image */
35 int length; /* Line length */
36 int bitsize; /* Size of bitmap */
37 int infosize; /* Size of header information */
38 BITMAPFILEHEADER header; /* File header */
41 /* Try opening the file; use "rb" mode to read this *binary* file. */
42 if ((fp = fopen(filename, "rb")) == NULL)
45 /* Read the file header and any following bitmap information... */
46 header.bfType = read_word(fp);
47 header.bfSize = read_dword(fp);
48 header.bfReserved1 = read_word(fp);
49 header.bfReserved2 = read_word(fp);
50 header.bfOffBits = read_dword(fp);
52 if (header.bfType != 0x4D42) /* Check for BM reversed... */
54 /* Not a bitmap file - return NULL... */
59 infosize = header.bfOffBits - 18;
60 if ((*info = (BITMAPINFO *)malloc(sizeof(BITMAPINFO))) == NULL)
62 /* Couldn't allocate memory for bitmap info - return NULL... */
67 (*info)->bmiHeader.biSize = read_dword(fp);
68 (*info)->bmiHeader.biWidth = read_long(fp);
69 (*info)->bmiHeader.biHeight = read_long(fp);
70 (*info)->bmiHeader.biPlanes = read_word(fp);
71 (*info)->bmiHeader.biBitCount = read_word(fp);
72 (*info)->bmiHeader.biCompression = read_dword(fp);
73 (*info)->bmiHeader.biSizeImage = read_dword(fp);
74 (*info)->bmiHeader.biXPelsPerMeter = read_long(fp);
75 (*info)->bmiHeader.biYPelsPerMeter = read_long(fp);
76 (*info)->bmiHeader.biClrUsed = read_dword(fp);
77 (*info)->bmiHeader.biClrImportant = read_dword(fp);
80 if (fread((*info)->bmiColors, infosize - 40, 1, fp) < 1)
82 /* Couldn't read the bitmap header - return NULL... */
88 /* Now that we have all the header info read in, allocate memory for *
89 * the bitmap and read *it* in... */
90 if ((bitsize = (*info)->bmiHeader.biSizeImage) == 0)
91 bitsize = ((*info)->bmiHeader.biWidth *
92 (*info)->bmiHeader.biBitCount + 7) / 8 *
93 abs((*info)->bmiHeader.biHeight);
95 if ((bits = malloc(bitsize)) == NULL)
97 /* Couldn't allocate memory - return NULL! */
103 if (fread(bits, 1, bitsize, fp) < bitsize)
105 /* Couldn't read bitmap - free memory and return NULL! */
112 /* Swap red and blue */
113 length = ((*info)->bmiHeader.biWidth * 3 + 3) & ~3;
114 for (y = 0; y < (*info)->bmiHeader.biHeight; y ++)
115 for (ptr = bits + y * length, x = (*info)->bmiHeader.biWidth;
124 /* OK, everything went fine - return the allocated bitmap... */
130 * 'read_word()' - Read a 16-bit unsigned integer.
133 static unsigned short /* O - 16-bit unsigned integer */
134 read_word(FILE *fp) /* I - File to read from */
136 unsigned char b0, b1; /* Bytes from file */
141 return ((b1 << 8) | b0);
146 * 'read_dword()' - Read a 32-bit unsigned integer.
149 static unsigned int /* O - 32-bit unsigned integer */
150 read_dword(FILE *fp) /* I - File to read from */
152 unsigned char b0, b1, b2, b3; /* Bytes from file */
159 return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
164 * 'read_long()' - Read a 32-bit signed integer.
167 static int /* O - 32-bit signed integer */
168 read_long(FILE *fp) /* I - File to read from */
170 unsigned char b0, b1, b2, b3; /* Bytes from file */
177 return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);