#include "bmpimage.h" BMPImage::BMPImage(BitmapFileHeader &fileHeader, BITMAPINFOHEADER &infoHeader, Pixel **pixelArray) { this->fileHeader = fileHeader; this->infoHeader = infoHeader; this->pixelArray = pixelArray; } const uint32_t &BMPImage::width() const { return this->infoHeader.BitmapWidth; } const uint32_t &BMPImage::height() const { return this->infoHeader.BitmapHeight; } void BMPImage::write(const std::string &filename) { { std::ofstream ofs(filename, std::ios_base::binary); ofs.write((char *) &this->fileHeader, sizeof(this->fileHeader)); ofs.write((char *) &this->infoHeader, sizeof(this->infoHeader)); uint32_t byteByRow = this->infoHeader.BitmapWidth * 3; uint8_t padding = 4 - this->infoHeader.BitmapWidth % 4; for (int i = 0; i < this->infoHeader.BitmapHeight; ++i) { ofs.write((char *) pixelArray[i], byteByRow); if (padding != 4) ofs.write(PADDING_ZEROES, padding); // Write padding } } } BMPImage readBMPImage(const std::string &filename) { BitmapFileHeader bitmapFileHeader; BITMAPINFOHEADER bitmapInfoHeader; Pixel **pixelArray; uint32_t DIB_Header_Size; { std::ifstream ifs(filename, std::ios_base::binary); if (!ifs.good()) { throw std::runtime_error("File read error"); } ifs.seekg(0, std::ios::beg); ifs.read((char *) &bitmapFileHeader, sizeof(bitmapFileHeader)); ifs.read((char *) &DIB_Header_Size, sizeof(DIB_Header_Size)); } if (DIB_Header_Size != 40) { throw std::runtime_error("Invalid header"); } { std::ifstream ifs(filename, std::ios_base::binary); if (!ifs.good()) { throw std::runtime_error("File read error"); } ifs.seekg(14, std::ios::beg); ifs.read((char *) &bitmapInfoHeader, sizeof(bitmapInfoHeader)); } pixelArray = new Pixel *[bitmapInfoHeader.BitmapHeight]; { std::ifstream ifs(filename, std::ios_base::binary); if (!ifs.good()) { throw std::runtime_error("File read error"); } ifs.seekg(bitmapFileHeader.imageDataOffset, std::ios::beg); uint32_t byteByRow = bitmapInfoHeader.BitmapWidth * 3; uint8_t padding = 4 - bitmapInfoHeader.BitmapWidth % 4; for (int i = 0; i < bitmapInfoHeader.BitmapHeight; ++i) { pixelArray[i] = new Pixel[bitmapInfoHeader.BitmapWidth]; ifs.read((char *) pixelArray[i], byteByRow); if (padding != 4) ifs.seekg(padding, std::ios_base::cur); // Skip padding } } return {bitmapFileHeader, bitmapInfoHeader, pixelArray}; }