add wraparound support to C2 physics
[openc2e.git] / bmpImage.cpp
bloba68c830a76a54f59a61ad1014f7ee683f1ce5f8a
1 /*
2 * bmpImage.cpp
3 * openc2e
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.
20 #include "bmpImage.h"
21 #include "endianlove.h"
22 #include "streamutils.h"
23 #include "exceptions.h"
24 #include "openc2e.h"
26 #include <iostream> // TODO: remove me
28 #define BI_RGB 0
29 #define BI_RLE8 1
30 #define BI_BITFIELDS 3
32 bmpImage::bmpImage(mmapifstream *in, std::string n) : creaturesImage(n) {
33 char magic[2];
34 in->read(magic, 2);
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) {
64 case BI_RGB:
65 case BI_BITFIELDS:
66 break;
68 case BI_RLE8:
69 std::cout << "Warning: sprite " << n << " is compressed." << std::endl;
70 break;
72 default:
73 throw creaturesException(n + " contains BMP data compressed in a way we don't understand.");
76 switch (biBitCount) {
77 case 8:
78 imgformat = if_paletted;
79 break;
81 case 24:
82 imgformat = if_24bit;
83 break;
85 default:
86 throw creaturesException(n + " contains BMP data of an unsupported bit depth.");
89 is_mutable = false;
91 bmpdata = in->map + dataoffset;
92 buffers = 0;
93 setBlockSize(biWidth, biHeight);
96 bmpImage::~bmpImage() {
97 freeData();
100 void bmpImage::freeData() {
101 for (unsigned int i = 0; i < m_numframes; i++) {
102 delete[] (char *)buffers[i];
105 delete[] widths;
106 delete[] heights;
107 delete[] buffers;
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);
143 curr_col++;
144 if (curr_col == widthinblocks) {
145 curr_col = 0;
146 curr_row++;
151 /* vim: set noet: */