Panda3D
 All Classes Functions Variables Enumerations
bmp.h
1 /* Filename: bmp.h
2  * Created by:
3  *
4  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5  *
6  * PANDA 3D SOFTWARE
7  * Copyright (c) Carnegie Mellon University. All rights reserved.
8  *
9  * All use of this software is subject to the terms of the revised BSD
10  * license. You should have received a copy of this license along
11  * with this source code in a file named "LICENSE."
12  *
13  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
14 
15 #ifndef _BMP_H_
16 #define _BMP_H_
17 
18 #include "pandabase.h"
19 #include "pnmimage_base.h"
20 
21 /* prototypes */
22 static unsigned long BMPlenfileheader(int classv);
23 static unsigned long BMPleninfoheader(int classv);
24 static unsigned long BMPlenrgbtable(int classv, unsigned long bitcount);
25 static unsigned long BMPlenline(int classv, unsigned long bitcount, unsigned long x);
26 static unsigned long BMPlenbits(int classv, unsigned long bitcount, unsigned long x, unsigned long y);
27 static unsigned long BMPlenfile(int classv, unsigned long bitcount, unsigned long x, unsigned long y);
28 static unsigned long BMPoffbits(int classv, unsigned long bitcount);
29 /*
30  * Classves of BMP files
31  */
32 
33 #define C_WIN 1
34 #define C_OS2 2
35 
36 static char er_internal[] = "%s: internal error!";
37 
38 static unsigned long
39 BMPlenfileheader(int classv)
40 {
41  switch (classv)
42  {
43  case C_WIN:
44  return 14;
45  case C_OS2:
46  return 14;
47  default:
48  pm_error(er_internal, "BMPlenfileheader");
49  return 0;
50  }
51 }
52 
53 static unsigned long
54 BMPleninfoheader(int classv)
55 {
56  switch (classv)
57  {
58  case C_WIN:
59  return 40;
60  case C_OS2:
61  return 12;
62  default:
63  pm_error(er_internal, "BMPleninfoheader");
64  return 0;
65  }
66 }
67 
68 static unsigned long
69 BMPlenrgbtable(int classv, unsigned long bitcount)
70 {
71  unsigned long lenrgb;
72 
73  if (bitcount > 8) {
74  return 0;
75  }
76 
77  if (bitcount < 1)
78  {
79  pm_error(er_internal, "BMPlenrgbtable");
80  return 0;
81  }
82  switch (classv)
83  {
84  case C_WIN:
85  lenrgb = 4;
86  break;
87  case C_OS2:
88  lenrgb = 3;
89  break;
90  default:
91  pm_error(er_internal, "BMPlenrgbtable");
92  return 0;
93  }
94 
95  return (1 << bitcount) * lenrgb;
96 }
97 
98 /*
99  * length, in bytes, of a line of the image
100  *
101  * Evidently each row is padded on the right as needed to make it a
102  * multiple of 4 bytes long. This appears to be true of both
103  * OS/2 and Windows BMP files.
104  */
105 static unsigned long
106 BMPlenline(int classv, unsigned long bitcount, unsigned long x)
107 {
108  unsigned long bitsperline;
109 
110  switch (classv)
111  {
112  case C_WIN:
113  break;
114  case C_OS2:
115  break;
116  default:
117  pm_error(er_internal, "BMPlenline");
118  return 0;
119  }
120 
121  bitsperline = x * bitcount;
122 
123  /*
124  * if bitsperline is not a multiple of 32, then round
125  * bitsperline up to the next multiple of 32.
126  */
127  if ((bitsperline % 32) != 0)
128  {
129  bitsperline += (32 - (bitsperline % 32));
130  }
131 
132  if ((bitsperline % 32) != 0)
133  {
134  pm_error(er_internal, "BMPlenline");
135  return 0;
136  }
137 
138  /* number of bytes per line == bitsperline/8 */
139  return bitsperline >> 3;
140 }
141 
142 /* return the number of bytes used to store the image bits */
143 static unsigned long
144 BMPlenbits(
145  int classv,
146  unsigned long bitcount,
147  unsigned long x,
148  unsigned long y)
149 {
150  return y * BMPlenline(classv, bitcount, x);
151 }
152 
153 /* return the offset to the BMP image bits */
154 static unsigned long
155 BMPoffbits(
156  int classv,
157  unsigned long bitcount)
158 {
159  return BMPlenfileheader(classv)
160  + BMPleninfoheader(classv)
161  + BMPlenrgbtable(classv, bitcount);
162 }
163 
164 /* return the size of the BMP file in bytes */
165 static unsigned long
166 BMPlenfile(
167  int classv,
168  unsigned long bitcount,
169  unsigned long x,
170  unsigned long y)
171 {
172  return BMPoffbits(classv, bitcount)
173  + BMPlenbits(classv, bitcount, x, y);
174 }
175 
176 #endif /* _BMP_H_ */
177