Last active
December 29, 2015 17:09
-
-
Save gofer/7701714 to your computer and use it in GitHub Desktop.
PPM type bitmap class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [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