Skip to content

Instantly share code, notes, and snippets.

@gofer
Last active December 29, 2015 17:09
Show Gist options
  • Save gofer/7701714 to your computer and use it in GitHub Desktop.
Save gofer/7701714 to your computer and use it in GitHub Desktop.
PPM type bitmap class
// [bitmap.hpp]
#ifndef __BITMAP_HPP__
#define __BITMAP_HPP__
#include <cstdint>
#include <vector>
typedef struct {uint8_t R, G, B;} RGB;
namespace Color {
const RGB Black = {0x00, 0x00, 0x00};
const RGB White = {0xFF, 0xFF, 0xFF};
};
class BitmapImage {
//private:
public:
uint32_t _width, _height, _max_gradation;
std::vector< std::vector<RGB> > _bitmap;
bool check_magic_number(const char*);
public:
BitmapImage();
BitmapImage(uint32_t, uint32_t, uint32_t);
bool read_file(const char*);
bool write_file(const char*);
RGB get_color(const uint32_t, const uint32_t);
void set_color(const uint32_t, const uint32_t, const RGB);
};
uint8_t max(uint8_t, uint8_t);
uint8_t max(uint8_t, uint8_t, uint8_t);
uint8_t min(uint8_t, uint8_t);
uint8_t min(uint8_t, uint8_t, uint8_t);
#endif
/**********************************************/
// [bitmap.cpp]
const char* PPM_MAGIC_NUMBER = "P6\n";
uint8_t max(uint8_t a, uint8_t b) {return (a > b) ? a : b;}
uint8_t max(uint8_t a, uint8_t b, uint8_t c) {return (max(a, b) > c) ? max(a, b) : c;}
uint8_t min(uint8_t a, uint8_t b) {return (a < b) ? a : b;}
uint8_t min(uint8_t a, uint8_t b, uint8_t c) {return (max(a, b) < c) ? max(a, b) : c;}
uint32_t strlen(const char* str) {int len = 0; while(str[len++] != '\0'); return len-1;}
uint32_t strncmp(const char* src, const char* dst, uint32_t size) {
uint32_t i;
for(i=0; i<size; ++i)
{if(src[i] == '\0' || dst[i] == '\0' || src[i] != dst[i]) break;}
return src[i] - dst[i];
}
int atoi(const char* buffer) {
int n = 0;
for(uint32_t i = 0; i<10 && buffer[i] != '\0'; ++i) {
if('0' <= buffer[i] && buffer[i] <= '9') {
n *= 10;
n += (int)(buffer[i] - '0');
} else {
return n;
}
}
return n;
}
BitmapImage::BitmapImage() {
_width = _height = _max_gradation = 0;
}
BitmapImage::BitmapImage(uint32_t width, uint32_t height, uint32_t max_gradation) {
_width = width;
_height = height;
_max_gradation = max_gradation;
_bitmap = std::vector< std::vector<RGB> >(_height);
for(uint32_t h=0; h<_height; ++h) {
_bitmap[h] = std::vector<RGB>(_width, Color::Black);
}
}
bool BitmapImage::check_magic_number(const char* buffer) {return strncmp(buffer, PPM_MAGIC_NUMBER, 3) == 0;}
bool BitmapImage::read_file(const char* input_file_name) {
std::ifstream ifs;
ifs.open(input_file_name, std::ios::binary);
{
char* buffer = new char[3];
ifs.read(buffer, 3);
delete buffer;
/*if( !check_magic_number(buffer) ) {
std::cerr << "Invalid PPM file" << std::endl;
ifs.close();
return false;
}*/
}
{
std::string width_str, height_str, max_gradation_str;
char buffer;
while(true) {
ifs.read(&buffer, 1);
if(buffer == ' ') break;
width_str += buffer;
}
while(true) {
ifs.read(&buffer, 1);
if(buffer == '\n') break;
height_str += buffer;
}
while(true) {
ifs.read(&buffer, 1);
if(buffer == '\n') break;
max_gradation_str += buffer;
}
_width = atoi(width_str.c_str());
_height = atoi(height_str.c_str());
_max_gradation = atoi(max_gradation_str.c_str());
}
_bitmap.resize(_height);
for(uint32_t h=0; h<_height; ++h) _bitmap[h].resize(_width, Color::Black);
{
char* buffer = new char[3];
for(uint32_t h=0; h<_height; ++h) {
for(uint32_t w=0; w<_width; ++w) {
RGB color;
ifs.read(reinterpret_cast<char*>(&color), 3);
_bitmap[h][w] = color;
}
}
delete buffer;
}
ifs.close();
return true;
}
bool BitmapImage::write_file(const char* output_file_name) {
std::ofstream ofs;
ofs.open(output_file_name, std::ios::binary);
ofs.write(PPM_MAGIC_NUMBER, 3);
char* buffer = new char[128];
sprintf(buffer, "%u %u\n%u\n", _width, _height, _max_gradation);
ofs.write(buffer, strlen(buffer));
delete buffer;
for(uint32_t h=0; h<_height; ++h) {
for(uint32_t w=0; w<_width; ++w) {
RGB color = _bitmap[h][w];
ofs.write(reinterpret_cast<char*>(&color), 3);
}
}
ofs.close();
return true;
}
RGB BitmapImage::get_color(const uint32_t width, const uint32_t height) {
if(width >= _width ) return _bitmap[height][0]; else
if(height >= _height) return _bitmap[0][width]; else
return _bitmap[height][width];
}
void BitmapImage::set_color(const uint32_t width, const uint32_t height, const RGB color) {
_bitmap[height][width].R = color.R;
_bitmap[height][width].G = color.G;
_bitmap[height][width].B = color.B;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment