c++ - Windows Bitmap encoder only writing bottom few thousand pixels -
the readbmpfromfile/stream
functions work fine. (still little slow otherwise work). writebmptofile/stream
functions work in create valid .bmp
file bottom few thousands of pixels, rest of file black.
it shouldn't hard see why, pixel data stored bottom top problem should near top of file.
reference: bmp file structure
original:
copy:
i stepped through debugger , data being copied containing object. shouldn't fail when reading file , writing back:
if(_keyboard->keydown(key_s)) { bitmapfiletype bmp_test; readbmpfromfile("maglot.bmp_test", bmp_test); //change filename not destroy original! writebmptofile("maglot_copy.bmp_test", bmp_test); //allegro's implementation test correct output against. //save_bmp("maglot_copy.bmp", image->getimage(), nullptr); }
bitmap class definition:
class bitmapfiletype { public: struct header { std::vector<unsigned char> file_signature; unsigned int file_size; unsigned short unused1; unsigned short unused2; unsigned int pixel_array_offset; unsigned int dib_header_size; unsigned int width; unsigned int height; unsigned short plane_count; unsigned short bpp; unsigned int compression_method; unsigned int raw_size; unsigned int print_resolution_horizontal; unsigned int print_resolution_vertical; unsigned int pallete_colors_count; unsigned int important_colors_count; header() : file_signature(2), file_size(0), unused1(0), unused2(0), pixel_array_offset(0), dib_header_size(0), width(0), height(0), plane_count(0), bpp(0), compression_method(0), raw_size(0), print_resolution_horizontal(0), print_resolution_vertical(0), pallete_colors_count(0), important_colors_count(0) { /* nothing */ } header(const header& other) : file_signature(other.file_signature), file_size(other.file_size), unused1(other.unused1), unused2(other.unused2), pixel_array_offset(other.pixel_array_offset), dib_header_size(other.dib_header_size), width(other.width), height(other.height), plane_count(other.plane_count), bpp(other.bpp), compression_method(other.compression_method), raw_size(other.raw_size), print_resolution_horizontal(other.print_resolution_horizontal), print_resolution_vertical(other.print_resolution_vertical), pallete_colors_count(other.pallete_colors_count), important_colors_count(other.important_colors_count) { /* nothing */ } header& operator=(const header& rhs) { if(this == &rhs) return *this; this->file_signature = rhs.file_signature; this->file_size = rhs.file_size; this->unused1 = rhs.unused1; this->unused2 = rhs.unused2; this->pixel_array_offset = rhs.pixel_array_offset; this->dib_header_size = rhs.dib_header_size; this->width = rhs.width; this->height = rhs.height; this->plane_count = rhs.plane_count; this->bpp = rhs.bpp; this->compression_method = rhs.compression_method; this->raw_size = rhs.raw_size; this->print_resolution_horizontal = rhs.print_resolution_horizontal; this->print_resolution_vertical = rhs.print_resolution_vertical; this->pallete_colors_count = rhs.pallete_colors_count; this->important_colors_count = rhs.important_colors_count; return *this; } }; struct pixeldata { std::vector<unsigned char> _pixel_data; pixeldata() : _pixel_data() { /* nothing */ } pixeldata(const pixeldata& other) : _pixel_data(other._pixel_data) { /* nothing */ } pixeldata(const std::vector<unsigned char>& pixel_data) : _pixel_data(pixel_data) { /* nothing */ } }; bitmapfiletype() : _header(), _data() { /* nothing */ } bitmapfiletype(const bitmapfiletype::header& header) : _header(header), _data() { /* nothing */ } bitmapfiletype(const bitmapfiletype::header& header, const pixeldata& data) : _header(header), _data(data) { /* nothing */ } bitmapfiletype& operator=(const bitmapfiletype& rhs) { if(this == &rhs) return *this; _header = rhs._header; _data = rhs._data; return *this; } const header& getheader() const { return _header; } header& getheader() { return const_cast<header&>(static_cast<const bitmapfiletype&>(*this).getheader()); } const pixeldata& getpixeldata() const { return _data; } pixeldata& getpixeldata() { return const_cast<pixeldata&>(static_cast<const bitmapfiletype&>(*this).getpixeldata()); } protected: private: header _header; pixeldata _data; };
function definitions:
#include "filetypeutility.h" #include <fstream> void writebmptofile(const std::string& filename, const bitmapfiletype& bmp) { std::ofstream ofs; ofs.open(filename); writebmptostream(ofs, bmp); ofs.close(); } void readbmpfromfile(const std::string& filename, bitmapfiletype& bmp) { std::ifstream ifs; ifs.open(filename); readbmpfromstream(ifs, bmp); ifs.close(); } void readbmpfromstream(std::istream& input_stream, bitmapfiletype& bmp) { if(input_stream.fail() || input_stream.bad() || input_stream.eof()) return; std::vector<unsigned char> file_signature(2); input_stream.read(reinterpret_cast<char*>(file_signature.data()), file_signature.size()); if((file_signature[0] != 'b' || file_signature[1] != 'm')) { input_stream.seekg(-2, std::ios_base::cur); input_stream.setstate(std::ios_base::failbit); return; } unsigned int file_size = 0; input_stream.read(reinterpret_cast<char*>(&file_size), sizeof(file_size)); unsigned short unused1 = 0; input_stream.read(reinterpret_cast<char*>(&unused1), sizeof(unused1)); unsigned short unused2 = 0; input_stream.read(reinterpret_cast<char*>(&unused2), sizeof(unused2)); unsigned int pixel_array_offset = 0; input_stream.read(reinterpret_cast<char*>(&pixel_array_offset), sizeof(pixel_array_offset)); unsigned int dib_header_size = 0; input_stream.read(reinterpret_cast<char*>(&dib_header_size), sizeof(dib_header_size)); unsigned int width = 0; input_stream.read(reinterpret_cast<char*>(&width), sizeof(width)); unsigned int height = 0; input_stream.read(reinterpret_cast<char*>(&height), sizeof(height)); unsigned short plane_count = 0; input_stream.read(reinterpret_cast<char*>(&plane_count), sizeof(plane_count)); unsigned short bpp = 0; input_stream.read(reinterpret_cast<char*>(&bpp), sizeof(bpp)); unsigned int compression_method = 0; input_stream.read(reinterpret_cast<char*>(&compression_method), sizeof(compression_method)); unsigned int raw_size = 0; input_stream.read(reinterpret_cast<char*>(&raw_size), sizeof(raw_size)); unsigned int print_resolution_horizontal = 0; input_stream.read(reinterpret_cast<char*>(&print_resolution_horizontal), sizeof(print_resolution_horizontal)); unsigned int print_resolution_vertical = 0; input_stream.read(reinterpret_cast<char*>(&print_resolution_vertical), sizeof(print_resolution_vertical)); unsigned int pallete_colors_count = 0; input_stream.read(reinterpret_cast<char*>(&pallete_colors_count), sizeof(pallete_colors_count)); unsigned int important_colors_count = 0; input_stream.read(reinterpret_cast<char*>(&important_colors_count), sizeof(important_colors_count)); std::vector<unsigned char> pixel_array(raw_size); input_stream.read(reinterpret_cast<char*>(pixel_array.data()), pixel_array.size()); bitmapfiletype::pixeldata bmppixels(pixel_array); bitmapfiletype::header bmpheader; bmpheader.file_signature = file_signature; bmpheader.file_size = file_size; bmpheader.unused1 = unused1; bmpheader.unused2 = unused2; bmpheader.pixel_array_offset = pixel_array_offset; bmpheader.dib_header_size = dib_header_size; bmpheader.width = width; bmpheader.height = height; bmpheader.plane_count = plane_count; bmpheader.bpp = bpp; bmpheader.compression_method = compression_method; bmpheader.raw_size = raw_size; bmpheader.print_resolution_horizontal = print_resolution_horizontal; bmpheader.print_resolution_vertical = print_resolution_vertical; bmpheader.pallete_colors_count = pallete_colors_count; bmpheader.important_colors_count = important_colors_count; bmp = bitmapfiletype(bmpheader, bmppixels); return; } void writebmptostream(std::ostream& output_stream, const bitmapfiletype& bmp) { if(output_stream.fail() || output_stream.bad() || output_stream.eof()) return; const bitmapfiletype::header& bmpheader(bmp.getheader()); output_stream.write(reinterpret_cast<const char*>(bmpheader.file_signature.data()), bmpheader.file_signature.size()); output_stream.write(reinterpret_cast<const char*>(&bmpheader.file_size), sizeof(bmpheader.file_size)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.unused1), sizeof(bmpheader.unused1)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.unused2), sizeof(bmpheader.unused2)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.pixel_array_offset), sizeof(bmpheader.pixel_array_offset)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.dib_header_size), sizeof(bmpheader.dib_header_size)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.width), sizeof(bmpheader.width)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.height), sizeof(bmpheader.height)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.plane_count), sizeof(bmpheader.plane_count)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.bpp), sizeof(bmpheader.bpp)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.compression_method), sizeof(bmpheader.compression_method)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.raw_size), sizeof(bmpheader.raw_size)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.print_resolution_horizontal), sizeof(bmpheader.print_resolution_horizontal)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.print_resolution_vertical), sizeof(bmpheader.print_resolution_vertical)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.pallete_colors_count), sizeof(bmpheader.pallete_colors_count)); output_stream.write(reinterpret_cast<const char*>(&bmpheader.important_colors_count), sizeof(bmpheader.important_colors_count)); const bitmapfiletype::pixeldata& bmppixeldata(bmp.getpixeldata()); output_stream.write(reinterpret_cast<const char*>(bmppixeldata._pixel_data.data()), bmppixeldata._pixel_data.size()); return; }
Comments
Post a Comment