Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Bmp.cpp
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: Bmp.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  BMP image file loader
13 */
14 
15 
16 #include "MemDebug.h"
17 #include "BMP.h"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 // +--------------------------------------------------------------------+
24 
26 : width(0), height(0), image(0)
27 { }
28 
29 BmpImage::BmpImage(short w, short h, unsigned long* hibits)
30 {
31  ZeroMemory(this, sizeof(BmpImage));
32 
33  width = w;
34  height = h;
35 
36  file_hdr.type = 19778; // 'BM'
37  file_hdr.size = sizeof(BmpFileHeader) +
38  sizeof(BmpInfoHeader) +
39  w * h * 3;
40 
41  file_hdr.offset = sizeof(BmpFileHeader) +
42  sizeof(BmpInfoHeader);
43 
47  info_hdr.planes = 1;
48  info_hdr.bit_count = 24;
49 
50  int pixels = width * height;
51 
52  image = new(__FILE__,__LINE__) DWORD [pixels];
53 
54  if (image && pixels) {
55  for (int i = 0; i < pixels; i++)
56  image[i] = hibits[i];
57  }
58 }
59 
61 {
62  delete [] image;
63 }
64 
65 // +--------------------------------------------------------------------+
66 
67 int BmpImage::Load(char *filename)
68 {
69  int status = BMP_INVALID;
70  FILE* f;
71 
72  fopen_s(&f, filename,"rb");
73  if (f == NULL)
74  return BMP_NOFILE;
75 
76  fread(&file_hdr.type, sizeof(WORD), 1, f);
77  fread(&file_hdr.size, sizeof(DWORD), 1, f);
78  fread(&file_hdr.rsvd1, sizeof(WORD), 1, f);
79  fread(&file_hdr.rsvd2, sizeof(WORD), 1, f);
80  fread(&file_hdr.offset, sizeof(DWORD), 1, f);
81  fread(&info_hdr, BMP_INFO_HDR_SIZE, 1, f);
82 
83  if (info_hdr.width > 32768 || info_hdr.height > 32768 ||
84  (info_hdr.width&3) || (info_hdr.height&3) ||
85  info_hdr.compression != 0) {
86  fclose(f);
87  return BMP_INVALID;
88  }
89 
90  width = (WORD) info_hdr.width;
91  height = (WORD) info_hdr.height;
92 
93  // read 256 color BMP file
94  if (info_hdr.bit_count == 8) {
95  fread(palette, sizeof(palette), 1, f);
96 
97  int pixels = width*height;
98 
99  delete [] image;
100  image = new(__FILE__,__LINE__) DWORD[pixels];
101  if (image == NULL)
102  return BMP_NOMEM;
103 
104  for (int row = height-1; row >= 0; row--) {
105  for (int col = 0; col < width; col++) {
106  BYTE index = fgetc(f);
107  image[row*width+col] = palette[index];
108  }
109  }
110 
111  status = BMP_OK;
112  }
113 
114  // read 24-bit (true COLOR) BMP file
115  else if (info_hdr.bit_count == 24) {
116  int pixels = width*height;
117 
118  delete [] image;
119  image = new(__FILE__,__LINE__) DWORD[pixels];
120  if (image == NULL)
121  return BMP_NOMEM;
122 
123  for (int row = height-1; row >= 0; row--) {
124  for (int col = 0; col < width; col++) {
125  DWORD blue = fgetc(f);
126  DWORD green = fgetc(f);
127  DWORD red = fgetc(f);
128 
129  image[row*width+col] = 0xff000000 | (red << 16) | (green << 8) | blue;
130  }
131  }
132 
133  status = BMP_OK;
134  }
135 
136  fclose(f);
137  return status;
138 }
139 
140 // +--------------------------------------------------------------------+
141 
142 int BmpImage::LoadBuffer(unsigned char* buf, int len)
143 {
144  int status = BMP_INVALID;
145  BYTE* fp;
146 
147  if (buf == NULL)
148  return BMP_NOFILE;
149 
150  fp = buf;
153 
154  if (info_hdr.width > 32768 || info_hdr.height > 32768 ||
155  (info_hdr.width&3) || (info_hdr.height&3) ||
156  info_hdr.compression != 0) {
157  return BMP_INVALID;
158  }
159 
160  width = (WORD) info_hdr.width;
161  height = (WORD) info_hdr.height;
162 
163  // read 256 color BMP file
164  if (info_hdr.bit_count == 8) {
165  memcpy(palette, fp, sizeof(palette));
166  fp += sizeof(palette);
167 
168  int pixels = width*height;
169 
170  delete [] image;
171  image = new(__FILE__,__LINE__) DWORD[pixels];
172  if (image == NULL)
173  return BMP_NOMEM;
174 
175  for (int row = height-1; row >= 0; row--) {
176  for (int col = 0; col < width; col++) {
177  BYTE index = *fp++;
178  image[row*width+col] = palette[index];
179  }
180  }
181 
182  status = BMP_OK;
183  }
184 
185  // read 24-bit (true COLOR) BMP file
186  else if (info_hdr.bit_count == 24) {
187  int pixels = width*height;
188 
189  delete [] image;
190  image = new(__FILE__,__LINE__) DWORD[pixels];
191  if (image == NULL)
192  return BMP_NOMEM;
193 
194  for (int row = height-1; row >= 0; row--) {
195  for (int col = 0; col < width; col++) {
196  DWORD blue = *fp++;
197  DWORD green = *fp++;
198  DWORD red = *fp++;
199 
200  image[row*width+col] = 0xff000000 | (red << 16) | (green << 8) | blue;
201  }
202  }
203 
204  status = BMP_OK;
205  }
206 
207  return status;
208 }
209 
210 // +--------------------------------------------------------------------+
211 
212 int BmpImage::Save(char *filename)
213 {
214  int status = BMP_INVALID;
215  FILE* f;
216 
217  fopen_s(&f, filename,"wb");
218  if (f == NULL)
219  return BMP_NOFILE;
220 
221  info_hdr.bit_count = 24;
222  info_hdr.compression = 0;
223 
224  fwrite(&file_hdr.type, sizeof(WORD), 1, f);
225  fwrite(&file_hdr.size, sizeof(DWORD), 1, f);
226  fwrite(&file_hdr.rsvd1, sizeof(WORD), 1, f);
227  fwrite(&file_hdr.rsvd2, sizeof(WORD), 1, f);
228  fwrite(&file_hdr.offset, sizeof(DWORD), 1, f);
229  fwrite(&info_hdr, BMP_INFO_HDR_SIZE, 1, f);
230 
231  // write 24-bit (TRUE COLOR) BMP file
232  for (int row = height-1; row >= 0; row--) {
233  for (int col = 0; col < width; col++) {
234  DWORD pixel = image[row*width+col];
235 
236  BYTE blue = (BYTE) ((pixel & 0x000000ff) >> 0);
237  BYTE green = (BYTE) ((pixel & 0x0000ff00) >> 8);
238  BYTE red = (BYTE) ((pixel & 0x00ff0000) >> 16);
239 
240  fwrite(&blue, 1, 1, f);
241  fwrite(&green, 1, 1, f);
242  fwrite(&red, 1, 1, f);
243  }
244  }
245 
246  status = BMP_OK;
247 
248  fclose(f);
249  return status;
250 }
251