ail now builds on Linux
[ail.git] / ail / bmp.cpp
blob0cd2324a6aedc524132652ed8963c3a0422d9f98
1 #include <ail/bmp.hpp>
3 #include <cstring>
5 #include <ail/memory.hpp>
6 #include <ail/file.hpp>
8 namespace ail
10 namespace
12 std::size_t const
13 bmp_header_size = 54,
14 bytes_per_pixel = 3, //24-bit
15 bmp_padding = 4,
16 dword_size = 4;
19 bmp::bmp():
20 buffer(0)
24 bmp::bmp(std::size_t width, std::size_t height):
25 buffer(0)
27 initialise(width, height);
30 bmp::~bmp()
32 release();
35 void bmp::initialise(std::size_t new_width, std::size_t new_height)
37 release();
38 width = new_width;
39 height = new_height;
40 process_image_size(width, height);
41 buffer = new char[image_size];
42 write_header();
45 std::size_t bmp::process_image_size(std::size_t width, std::size_t height)
47 bytes_per_line = width * bytes_per_pixel;
48 std::size_t remainder = bytes_per_line % bmp_padding;
49 if(remainder != 0)
50 bytes_per_line += bmp_padding - remainder;
51 image_size = bmp_header_size + height * bytes_per_line;
52 return image_size;
55 void bmp::set_pixel(std::size_t x, std::size_t y, long value)
57 if(x < 0 || x >= width)
58 throw exception("Invalid x coordinate");
59 if(y < 0 || y >= height)
60 throw exception("Invalid y coordinate");
61 std::size_t offset = bmp_header_size + (height - y) * bytes_per_line + x * bytes_per_pixel;
62 write_little_endian(static_cast<ulong>(value), buffer + offset, bytes_per_pixel);
65 bool bmp::write(std::string const & file_name)
67 file bmp_file;
68 if(!bmp_file.open_create(file_name))
69 return false;
70 bmp_file.write(buffer, image_size);
71 bmp_file.close();
72 return true;
75 void bmp::write_header()
77 char * data =
78 "\x42\x4D\xF6\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00"
79 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x18\x00\x00\x00"
80 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
81 "\x00\x00\x00\x00\x00\x00";
83 std::memcpy(buffer, data, bmp_header_size);
84 write_little_endian(static_cast<ulong>(width), buffer + 18, dword_size);
85 write_little_endian(static_cast<ulong>(height), buffer + 22, dword_size);
86 write_little_endian(static_cast<ulong>(image_size - bmp_header_size), buffer + 34, dword_size);
89 void bmp::release()
91 if(buffer != 0)
93 delete buffer;
94 buffer = 0;