#include "bmpimage.h" BMPImage::BMPImage(const BitmapFileHeader &fileHeader, const 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 } } } Pixel **BMPImage::pixels(){ return this->pixelArray; } Pixel **BMPImage::pixels_copy() { Pixel **newPixelArray; newPixelArray = new Pixel *[this->infoHeader.BitmapHeight]; for (int i = 0; i < this->infoHeader.BitmapHeight; ++i) { newPixelArray[i] = new Pixel[this->infoHeader.BitmapWidth]; std::copy(this->pixelArray[i], this->pixelArray[i] + this->infoHeader.BitmapWidth, newPixelArray[i]); } return newPixelArray; } BitmapFileHeader BMPImage::fileHeader_copy() { return this->fileHeader; } BITMAPINFOHEADER BMPImage::infoHeader_copy() { return this->infoHeader; } BMPImage::~BMPImage() { for (int i = 0; i < this->infoHeader.BitmapHeight; ++i) { delete[] this->pixelArray[i]; } delete[] this->pixelArray; } 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}; }