5 * Created by Alyssa Milburn on Wed Feb 20 2008.
6 * Copyright (c) 2008 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
21 #include "endianlove.h"
22 #include "streamutils.h"
23 #include "exceptions.h"
26 #include <iostream> // TODO: remove me
30 #define BI_BITFIELDS 3
32 bmpImage::bmpImage(mmapifstream
*in
, std::string n
) : creaturesImage(n
) {
35 if (std::string(magic
, 2) != "BM")
36 throw creaturesException(n
+ " doesn't seem to be a BMP file.");
38 in
->seekg(8, std::ios::cur
); // skip filesize and reserved bytes
40 uint32 dataoffset
= read32(*in
);
42 uint32 biSize
= read32(*in
);
43 if (biSize
!= 40) // win3.x format, which the seamonkeys files are in
44 throw creaturesException(n
+ " is a BMP format we don't understand.");
46 biWidth
= read32(*in
);
47 biHeight
= read32(*in
);
49 uint16 biPlanes
= read16(*in
);
50 if (biPlanes
!= 1) // single image plane
51 throw creaturesException(n
+ " contains BMP data we don't understand.");
53 uint16 biBitCount
= read16(*in
);
54 uint32 biCompression
= read32(*in
);
56 // and now for some stuff we really don't care about
57 uint32 biSizeImage
= read32(*in
);
58 uint32 biXPelsPerMeter
= read32(*in
);
59 uint32 biYPelsPerMeter
= read32(*in
);
60 uint32 biClrUsed
= read32(*in
);
61 uint32 biClrImportant
= read32(*in
);
63 switch (biCompression
) {
69 std::cout
<< "Warning: sprite " << n
<< " is compressed." << std::endl
;
73 throw creaturesException(n
+ " contains BMP data compressed in a way we don't understand.");
78 imgformat
= if_paletted
;
86 throw creaturesException(n
+ " contains BMP data of an unsupported bit depth.");
91 bmpdata
= in
->map
+ dataoffset
;
93 setBlockSize(biWidth
, biHeight
);
96 bmpImage::~bmpImage() {
100 void bmpImage::freeData() {
101 for (unsigned int i
= 0; i
< m_numframes
; i
++) {
102 delete[] (char *)buffers
[i
];
110 void bmpImage::setBlockSize(unsigned int blockwidth
, unsigned int blockheight
) {
111 if (buffers
) freeData();
113 unsigned int widthinblocks
= biWidth
/ blockwidth
;
114 caos_assert(widthinblocks
* blockwidth
== biWidth
);
115 unsigned int heightinblocks
= biHeight
/ blockheight
;
116 caos_assert(heightinblocks
* blockheight
== biHeight
);
118 m_numframes
= widthinblocks
* heightinblocks
;
119 widths
= new unsigned short[m_numframes
];
120 heights
= new unsigned short[m_numframes
];
121 buffers
= new void *[m_numframes
];
123 unsigned int curr_row
= 0, curr_col
= 0;
124 for (unsigned int i
= 0; i
< m_numframes
; i
++) {
125 widths
[i
] = blockwidth
;
126 heights
[i
] = blockheight
;
128 unsigned int buffersize
= blockwidth
* blockheight
;
129 if (imgformat
== if_24bit
) { buffersize
*= 3; }
131 buffers
[i
] = new char *[buffersize
];
133 for (unsigned int j
= 0; j
< blockheight
; j
++) {
134 unsigned int srcoffset
= ((biHeight
- 1) * biWidth
) - (biWidth
* blockheight
* curr_row
) - (biWidth
* j
) + (curr_col
* blockwidth
);
135 unsigned int destoffset
= blockwidth
* j
;
136 unsigned int datasize
= blockwidth
;
138 if (imgformat
== if_24bit
) { srcoffset
*= 3; destoffset
*= 3; datasize
*= 3; }
140 memcpy((char *)buffers
[i
] + destoffset
, (char *)bmpdata
+ srcoffset
, datasize
);
144 if (curr_col
== widthinblocks
) {