Иногда бывает нужно в коде в целях отладки сбрасывать какие то изображения что бы посмотреть.
Например бывает очень нужно в OpenGL приложениях посмотреть что ушло в текстуру или что там получилось.
Во общем кидаю парочку простых функций для дампа в ppm/pbm которые можно быстро вставить и скомпилить.
Может кому то пригодится, одно замечание 32-битные изображения не могут быть сохранены в ppm/pbm формате и будут сконвертированы в 24-битные.
| Скрытый текст |
| unsigned short calculate_stride(unsigned int w, unsigned char bypp)
{
unsigned short pitch = 0;
pitch = w * bypp;
switch (bypp<<3)
{
case 1: pitch = (pitch+7)/8; break;
case 4: pitch = (pitch+1)/2; break;
}
// 4-byte aligning
pitch = (pitch + 3) & ~3;
return pitch;
}
struct cm_RGB_2_RGB {
enum {
r = 0, g = 1, b = 2
};
};
struct cm_BRG_2_RGB {
enum {
r = 1, g = 2, b = 0
};
};
struct cm_BGR_2_RGB {
enum {
r = 2, g = 1, b = 0
};
};
template< typename color_model >
bool graphics_algs::export_2ppm( unsigned int w, unsigned int h, int stride, unsigned char bypp, const void* data, std::ostream& stream )
{
assert( stream.good() && stream.flags() & std::ios::binary|std::ios::out);
if( !stream.good() ) return false;
stream << (1 == bypp ? "P5" : "P6") << "\n";
stream << w << "\n" << h << "\n";
stream << 255 << "\n";
if(4 == bypp) { //convert to 24 bit PPM
const unsigned short new_stride = calculate_stride(w, 3);
for(unsigned int r = 0; r < h; ++r)
{
const unsigned char *_data = (const unsigned char*)data + (r*stride);
for(unsigned int c = 0; c < w; ++c)
{
stream.put(*(_data+c*4+color_model::r));
stream.put(*(_data+c*4+color_model::g));
stream.put(*(_data+c*4+color_model::b));
}
for(int s = 0; s < new_stride - (w*3); ++s) {
stream.put(0);
}
}
} else {
for(unsigned int y = 0; y < h; y++) {
stream.write( (const char*)data + y * stride, w * bypp);
}
}
return true;
}
|
| |