user2705939
user2705939

Reputation:

Read/Write SImple BMP Image C++

I am trying to read simple BMP file and without performing any operations I am writing it back again to file.

I don't know where the mistake is in reading the file or writing it back. I have added padding while reading as well as while writing

-- File-Read --.

std::vector<char> tempImageData;
/*tempImageData.resize(m_bmpInfo->imagesize);
file.seekg(m_bmpHeader->dataoffset);
file.read(&tempImageData[0], m_bmpInfo->imagesize);
file.close();*/
tempImageData.resize(m_bmpInfo->imagesize);
int padding = 0;
while (((m_bmpInfo->width*3+padding) % 4) != 0 )
    padding++;
for(unsigned int i = 0 ; i < m_bmpInfo->height ; i++)
{
    file.seekg(m_bmpHeader->dataoffset + i*(m_bmpInfo->width*3 + padding));
    file.read(&tempImageData[i*m_bmpInfo->width*3], i*m_bmpInfo->width*3);
}
file.close();
//bitmaps are stored as BGR -- lets convert to RGB
assert(m_bmpInfo->imagesize % 3 == 0);

for (auto i = tempImageData.begin(); i != tempImageData.end(); i+=3)
{
    m_data_red.push_back(*(i+2));
    m_data_green.push_back(*(i+1));
    m_data_blue.push_back(*(i+0));
}

-- write code

file.write(reinterpret_cast<const char*>(m_bmpHeader), sizeof(BITMAPFILEHEADER));
file.write(reinterpret_cast<const char*>(m_bmpInfo), sizeof(BITMAPINFOHEADER));

// this is wrong.. format asks for bgr.. we are putting all r, all g, all b
std::vector<char> img;
img.reserve(m_data_red.size() + m_data_green.size() + m_data_blue.size());

for(unsigned int i = 0 ; i < m_data_red.size() ; i++)
{
    img.push_back(m_data_blue[i]);
    img.push_back(m_data_green[i]);
    img.push_back(m_data_red[i]);
}

char bmppad[3] = {0};

for(unsigned int i = 0 ; i < m_bmpInfo->height ; i++)
{
    // maybe something is wrong
    file.write(reinterpret_cast<const char*>(&img[i*m_bmpInfo->width*3]), m_bmpInfo->width * 3 * sizeof(unsigned char));
    file.write(bmppad, 1 * ((4-(m_bmpInfo->width*3)%4)%4) * sizeof(char));
}

file.close();

But the results are weird.

Output image------Input image

enter image description here Input Image

Upvotes: 3

Views: 2468

Answers (1)

The Dark
The Dark

Reputation: 8514

As the padding is added to every row, I think you need to change this line:

file.seekg(m_bmpHeader->dataoffset + i*m_bmpInfo->width*3 + padding);

to this:

file.seekg(m_bmpHeader->dataoffset + i*(m_bmpInfo->width*3 + padding));

It also might be easier to save the calculated padding rather than calculating it in two different ways.

Edit: Without all the code to debug through, it is a bit hard to pinpoint, but there is an error on this line:

file.read(&tempImageData[i*m_bmpInfo->width*3], i*m_bmpInfo->width*3);

you should not have the i* part in the amount you are reading. This means at row 200 you are reading 200 rows worth of data into the array, possibly overwriting the end of the array. once you are more than half way through the image, which is interesting given your output.

Upvotes: 5

Related Questions