1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: bitmap.h,v 1.3 2004/06/30 16:44:52 asuraparaju Exp $ $Name: Dirac_1_0_2 $
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
15 *
16 * The Original Code is BBC Research and Development code.
17 *
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
22 *
23 * Contributor(s):
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28 * the GPL or the LGPL are applicable instead of those above. If you wish to
29 * allow use of your version of this file only under the terms of the either
30 * the GPL or LGPL and not to allow others to use your version of this file
31 * under the MPL, indicate your decision by deleting the provisions above
32 * and replace them with the notice and other provisions required by the GPL
33 * or LGPL. If you do not delete the provisions above, a recipient may use
34 * your version of this file under the terms of any one of the MPL, the GPL
35 * or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37
38 /***********************************************************************
39 File bitmap.h
40
41 Defines bitmap header class for uncompressed image IO.
42 Bitmap files are native to Windows on X86 and usually have a file
43 extension .BMP.
44
45 This class only supports uncompressed bitmaps using
46 24 bits per pixel.These are the common form of .BMP file.
47
48 I have tried to make the class platform independent - no guarantee.
49
50 At present the only useful parameters from the header seem to be the
51 width and height of the bitmap.
52
53 The bitmap format used (24bit uncompressed)is as follows:
54
55 BitMapFileHeader: 14 bytes
56 signature: 2 bytes Always 'BM'
57 fileSize: 4 bytes File size in bytes
58 reserved: 2 bytes
59 reserved: 2 bytes
60 dataOffset: 4 bytes Offset of raster data from beginning of file
61
62 BitMapInfoHeader: 40 bytes
63 size: 4 bytes Size of InfoHeader = 40
64 width: 4 bytes Bitmap width (pixels)
65 height: 4 bytes Bitmap height (pixels)
66 planes: 2 bytes Number of planes = 1
67 bitCount: 2 bytes Bits per pixel = 24
68 compression: 4 bytes Type of compression = 0 (no compression)
69 imageSize: 4 bytes Bytes of raster image data (including pading)
70 = 0 (valid for uncompressed)
71 xPixelsPerM 4 bytes Horizontal pixels per metre (meaningless) = 0
72 yPixelsPerM 4 bytes Vertical pixels per metre (meaningless) = 0
73 coloursUsed 4 bytes Number of colours used = 0
74 coloursImportant 4 bytes Number of important colours = 0
75
76 BitMapLine: multiple of 4 bytes = height*4*((3*width + 3)/4)
77 width*BGRTriple 3*Width bytes
78 padding Up to 3 bytes
79
80 BGRTriple: 3 bytes
81 blue: 1 byte
82 green: 1 byte
83 red: 1 byte
84
85 Original author: Tim Borer
86 *********************************************************************/
87
88 #ifndef dirac_utilities_bitmap
89 #define dirac_utilities_bitmap
90
91 #include <iosfwd>
92
93 namespace dirac_vu { //dirac video utilities namespace
94
95 class BitmapHeader {
96 public:
97 BitmapHeader() {} //used for reading bitmaps
98 BitmapHeader(int x, int y): w(x), h(y) {}
99 int width() const {
100 return w; }
101 void width(int x) {
102 w = x;}
103 int height() const {
104 return h; }
105 void height(int y) {
106 h = y; }
107 //Size of one picture line, in bytes, including padding
108 int lineBufferSize() const {
109 return 4*((3*w + 3)/4); }
110 friend std::ostream& operator<<(std::ostream& stream,
111 const BitmapHeader& header) {
112 return header.putTo(stream); }
113 friend std::istream& operator>>(std::istream& stream,
114 BitmapHeader& header) {
115 return header.getFrom(stream); }
116 private:
117 std::ostream& putTo(std::ostream& output) const;
118 std::istream& getFrom(std::istream& input);
119 int w;
120 int h;
121 };
122
123 } // end namespace dirac_vu
124
125 #endif // dirac_utilities_bitmap
1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: bitmap.cpp,v 1.3 2004/06/30 16:44:52 asuraparaju Exp $ $Name: Dirac_1_0_2 $
4 *
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 *
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
15 *
16 * The Original Code is BBC Research and Development code.
17 *
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
22 *
23 * Contributor(s):
24 * Tim Borer (Original Author)
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
28 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
29 * the GPL or the LGPL are applicable instead of those above. If you wish to
30 * allow use of your version of this file only under the terms of the either
31 * the GPL or LGPL and not to allow others to use your version of this file
32 * under the MPL, indicate your decision by deleting the provisions above
33 * and replace them with the notice and other provisions required by the GPL
34 * or LGPL. If you do not delete the provisions above, a recipient may use
35 * your version of this file under the terms of any one of the MPL, the GPL
36 * or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
38
39 #include <ostream>
40 #include <istream>
41
42 #include <iostream>
43
44 #include "bitmap.h"
45
46 namespace {
47
48 //Funtions to read and write a sequence of little endian bytes,
49 //stored in a byte array,
50 //to/from an integer in an endian independent way.
51 //Functions assume ints are at least 4 bytes.
52
53 int read2bytes(const char* bytes) {
54 int value=0;
55 value |= (*(bytes+1))& 0xff;
56 value <<= 8;
57 value |= ( (*bytes)& 0xff );
58 return value; }
59
60 int read4bytes(const char* bytes) {
61 int value=0;
62 value |= (*(bytes+3))& 0xff;
63 value <<= 8;
64 value |= (*(bytes+2))& 0xff;
65 value <<= 8;
66 value |= (*(bytes+1))& 0xff;
67 value <<= 8;
68 value |= ( (*bytes)& 0xff );
69 return value; }
70
71 void write2bytes(char* bytes, int value) {
72 (*bytes) = value & 0xff;
73 value >>= 8;
74 (*(bytes+1)) = value & 0xff;
75 value >>= 8;
76 }
77
78 void write4bytes(char* bytes, int value) {
79 (*bytes) = value & 0xff;
80 value >>= 8;
81 (*(bytes+1)) = value & 0xff;
82 value >>= 8;
83 (*(bytes+2)) = value & 0xff;
84 value >>= 8;
85 (*(bytes+3)) = value & 0xff;
86 value >>= 8;
87 }
88
89 } //end anonymous namespace
90
91 namespace dirac_vu { //dirac video utilities namespace
92
93 std::ostream& BitmapHeader::putTo(std::ostream& output) const {
94 //Define variables for bitmap parameters
95 const char signature[2] = { 'B', 'M' };
96 const int dataOffset = 54;
97 const int fileSize = dataOffset + height()*lineBufferSize();
98 const int reserved = 0;
99 const int size = 40;
100 const int planes = 1;
101 const int bitCount = 24;
102 const int compression = 0;
103 const int imageSize = 0;
104 const int xPixelsPerM = 0, yPixelsPerM = 0;
105 const int coloursUsed = 0 ;
106 const int coloursImportant = 0;
107 //Define buffer to read bytes into.
108 const int bufferSize = 54;
109 char buffer[bufferSize];
110 //Write header parameters into buffer
111 *buffer = signature[0];
112 *(buffer+1) = signature[1];
113 write4bytes(buffer+2, fileSize);
114 write4bytes(buffer+6, reserved);
115 write4bytes(buffer+10, dataOffset);
116 write4bytes(buffer+14, size);
117 write4bytes(buffer+18, width());
118 write4bytes(buffer+22, height());
119 write2bytes(buffer+26, planes);
120 write2bytes(buffer+28, bitCount);
121 write4bytes(buffer+30, compression);
122 write4bytes(buffer+34, imageSize);
123 write4bytes(buffer+38, xPixelsPerM);
124 write4bytes(buffer+42, yPixelsPerM);
125 write4bytes(buffer+46, coloursUsed);
126 write4bytes(buffer+50, coloursImportant);
127 //Do pre & post processing by creating a sentry object
128 std::ostream::sentry s(output);
129 //Check all is well for output
130 if (!s) {
131 output.setstate(std::ios::failbit);
132 return output; }
133 //Use stream buffer directly for efficiency
134 std::streambuf& outbuf = *output.rdbuf();
135 if (outbuf.sputn(buffer, bufferSize) < bufferSize) {
136 output.setstate(std::ios::eofbit);
137 output.setstate(std::ios::failbit); }
138 return output; }
139
140 std::istream& BitmapHeader::getFrom(std::istream& input) {
141 //Define variables for bitmap parameters
142 char signature[2];
143 int fileSize;
144 int dataOffset;
145 int size;
146 int planes;
147 int bitCount;
148 int compression;
149 int imageSize;
150 int xPixelsPerM, yPixelsPerM;
151 int coloursUsed;
152 int coloursImportant;
153 //Define buffer to read bytes into.
154 const int bufferSize = 54;
155 char buffer[bufferSize];
156 //Ensure pre & post processing by constructing a sentry object
157 //The "true" parameter means "don't ignore leading whitespace"
158 std::istream::sentry s(input, true);
159 //Check that all is well for input to start
160 if (!s) {
161 input.setstate(std::ios::failbit);
162 return input; }
163 //Use stream buffer directly to avoid the overhead of sentry
164 //objects created by the unformatted stream I/O functions
165 //First create a reference to the input stream buffer
166 std::streambuf& inbuf = *input.rdbuf();
167 if (inbuf.sgetn(buffer, bufferSize) < bufferSize) {
168 input.setstate(std::ios_base::eofbit);
169 input.setstate(std::ios_base::failbit); }
170 signature[0]=*buffer;
171 signature[1]=*(buffer+1);
172 if ( (signature[0]!='B') || (signature[1]!='M') ) input.setstate(std::ios::failbit);
173 fileSize = read4bytes(buffer+2);
174 dataOffset= read4bytes(buffer+10);
175 //Reposition input buffer to skip over extra header data if necessary
176 //Should check success of operation (see The C++ Stand Lib, Josuttis, p665)
177 if (dataOffset>54) inbuf.pubseekoff(dataOffset-54, std::ios_base::cur, std::ios_base::in);
178 size = read4bytes(buffer+14);
179 w = read4bytes(buffer+18);
180 h = read4bytes(buffer+22);
181 if ( fileSize != (dataOffset + height()*lineBufferSize()) ) input.setstate(std::ios::failbit);
182 planes = read2bytes(buffer+26);
183 if ( planes != 1 ) input.setstate(std::ios::failbit);
184 bitCount = read2bytes(buffer+28);
185 if ( bitCount != 24 ) input.setstate(std::ios::failbit);
186 compression = read4bytes(buffer+30);
187 if ( compression != 0 ) input.setstate(std::ios::failbit);
188 imageSize = read4bytes(buffer+34);
189 xPixelsPerM = read4bytes(buffer+38);
190 yPixelsPerM = read4bytes(buffer+42);
191 coloursUsed = read4bytes(buffer+46);
192 coloursImportant = read4bytes(buffer+50);
193 return input; }
194
195 } // end namespace dirac_vu