# Program supposed to read in a BMP file and write a PPM file.



## sabre71789 (Sep 28, 2008)

It's supposed to read in a .bmp file and then reverse all the colors, and then write it as a .ppm file. I am currently just trying to get it to read in the .bmp file and write a .bmp file, reversed. But it writes a corrupt file... Please help...


```
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

class BITMAPFILEHEADER /**** BMP file header class ****/
{
	public:
		unsigned short bfType; /* Magic number for file */
		unsigned long int bfSize; /* Size of file */
		unsigned short bfReserved1; /* Reserved */
		unsigned short bfReserved2; /* ... */
		unsigned int bfOffBits; /* Offset to bitmap data */

		int BITMAPFILEHEADER::ReadBmpFileHeader ( BITMAPFILEHEADER *FileHeader, ifstream &fp) 
	{
		fp.read ((char*)&FileHeader->bfType, sizeof(FileHeader->bfType));
		fp.read ((char*)&FileHeader->bfSize, sizeof(FileHeader->bfSize));
		fp.read ((char*)&FileHeader->bfReserved1, sizeof(FileHeader->bfReserved1) );
		fp.read ((char*)&FileHeader->bfReserved2, sizeof(FileHeader->bfReserved2) );
		fp.read ((char*)&FileHeader->bfOffBits, sizeof(FileHeader->bfOffBits));
		return 1;
	}

		int BITMAPFILEHEADER::WriteBmpFileHeader ( BITMAPFILEHEADER *FileHeader, ofstream &fp)
	{
		fp.write ((char*)&FileHeader->bfType, sizeof(FileHeader->bfType) );
		fp.write ((char*)&FileHeader->bfSize, sizeof(FileHeader->bfSize) );
		fp.write ((char*)&FileHeader->bfReserved1, sizeof(FileHeader->bfReserved1) );
		fp.write ((char*)&FileHeader->bfReserved2, sizeof(FileHeader->bfReserved2) );
		fp.write ((char*)&FileHeader->bfOffBits, sizeof(FileHeader->bfOffBits) );
		return 1;
	}


};

# define BF_TYPE 0x4D42 /* "MB" */

class BITMAPINFOHEADER /**** BMP file info structure ****/
{
	public:
		unsigned long int biSize; /* Size of info header */
		int biWS; /* Width of image */
		int biHS; /* Height of image */
		unsigned short int biPlanes; /* Number of color planes */
		unsigned short int biBitCount; /* Number of bits per pixel */
		unsigned int biCompression; /* Type of compression to use */
		unsigned int biSZ; /* Size of image data */
		int biXPelsPerMeter; /* X pixels per meter */
		int biYPelsPerMeter; /* Y pixels per meter */
		unsigned int biClrUsed; /* Number of colors used */
		unsigned int biClrImportant; /* Number of important colors */


		int BITMAPINFOHEADER::ReadBmpInfoHeader (BITMAPINFOHEADER *InfoHeader, ifstream &fp)
		{
			fp.read ((char*)&InfoHeader->biSize, sizeof(InfoHeader->biSize));
			fp.read ((char*)&InfoHeader->biWS, sizeof(InfoHeader->biWS));
			fp.read ((char*)&InfoHeader->biHS, sizeof(InfoHeader->biHS));
			fp.read ((char*)&InfoHeader->biPlanes, sizeof(InfoHeader->biPlanes));
			fp.read ((char*)&InfoHeader->biBitCount, sizeof(InfoHeader->biBitCount));
			fp.read ((char*)&InfoHeader->biCompression, sizeof(InfoHeader->biCompression));
			fp.read ((char*)&InfoHeader->biSZ, sizeof(InfoHeader->biSZ));
			fp.read ((char*)&InfoHeader->biXPelsPerMeter, sizeof(InfoHeader->biXPelsPerMeter));
			fp.read ((char*)&InfoHeader->biYPelsPerMeter, sizeof(InfoHeader->biYPelsPerMeter));
			fp.read ((char*)&InfoHeader->biClrUsed, sizeof(InfoHeader->biClrUsed));
			fp.read ((char*)&InfoHeader->biClrImportant, sizeof(InfoHeader->biClrImportant));
			return 1;
		}

		int BITMAPINFOHEADER::WriteBmpInfoHeader( BITMAPINFOHEADER *InfoHeader, ofstream &fp) 
		{
			fp.write ((char*)&InfoHeader->biSize, sizeof(InfoHeader->biSize));
			fp.write ((char*)&InfoHeader->biWS, sizeof(InfoHeader->biWS));
			fp.write ((char*)&InfoHeader->biHS, sizeof(InfoHeader->biHS));
			fp.write ((char*)&InfoHeader->biPlanes, sizeof(InfoHeader->biPlanes));
			fp.write ((char*)&InfoHeader->biBitCount, sizeof(InfoHeader->biBitCount));
			fp.write ((char*)&InfoHeader->biCompression, sizeof(InfoHeader->biCompression));
			fp.write ((char*)&InfoHeader->biSZ, sizeof(InfoHeader->biSZ));
			fp.write ((char*)&InfoHeader->biXPelsPerMeter, sizeof(InfoHeader->biXPelsPerMeter));
			fp.write ((char*)&InfoHeader->biYPelsPerMeter, sizeof(InfoHeader->biYPelsPerMeter));
			fp.write ((char*)&InfoHeader->biClrUsed, sizeof(InfoHeader->biClrUsed));
			fp.write ((char*)&InfoHeader->biClrImportant, sizeof(InfoHeader->biClrImportant));
			return 1;
		}


};



//////////////////////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char *argv[]) 
{
	BITMAPFILEHEADER bfh;
	BITMAPINFOHEADER bhd;

	ifstream fp1 (argv[1], ios::in|ios::binary);

	if (!fp1.is_open())
	{
		cout << "Usage: " << argv[0] << " filename "<< endl;
		// fprintf(stderr,"Usage: %s filename\n",argv[0]);
		return 1;
	}

	ofstream fp2 (argv[2], ios::out|ios::binary);
	if (!fp2.is_open())
	{
		cout << "Usage: " << argv[0] << " filename "<< endl;
		// fprintf(stderr,"Usage: %s filename\n",argv[0]);
		return 1;
	}

	int success = 0 ;


	success = bfh.ReadBmpFileHeader( &bfh, fp1) ;
	if (!success)
	{
		/* Couldn't read the file header - return NULL... */
		fp1.close();
		return -1;
	}

	if (bfh.bfType != BF_TYPE) /* Check for BM reversed, ie MB... */
	{
		cout << "ID is: " << bfh.bfType << " Should have been" << 'M'*256+'B';
		cout << bfh.bfType/256 << " " << bfh.bfType%256 << endl;
		/* Not a bitmap file - return NULL... */
		fp1.close();
		return 1;
	}


	cout << "Image data Size: " << bfh.bfSize << endl;

	success = 0;
	success = bhd.ReadBmpInfoHeader( &bhd, fp1);
	if (!success)
	{
		/* Couldn't read the file header - return NULL... */
		fp2.close();
		return -1;
	}



	cout << "Image Withd Size: " << bhd.biWS << endl;

	cout << "Image Height Size: " << bhd.biHS << endl;

	cout<< "Bitcount: " << bhd.biBitCount << endl;
	// fprintf(stderr,"Bitcount: %d\n",bhd.biBitCount);

	bfh.WriteBmpFileHeader( &bfh, fp2);
	bhd.WriteBmpInfoHeader( &bhd, fp2);

	unsigned char r, g, b;
	for (int i=0 ; i < bhd.biWS; i++)
	{
		for (int j=0 ; j < bhd.biHS; j++) 
		{
			fp1.read ((char*)&r, 1);
			fp1.read ((char*)&g, 1);
			fp1.read ((char*)&b, 1);
			//fread (&g, sizeof(char), 1, fp1);
			//fread (&b, sizeof(char), 1, fp1);
			//r = 255 - r;
			//g = 255 - g;
			//b = 255 - b;
			fp2.write ((char*)&r, sizeof(char));
			fp2.write ((char*)&g, sizeof(char));
			fp2.write ((char*)&b, sizeof(char));
			// fwrite (&b, sizeof(char), 1, fp2);

		}

		fp1.close ();
		fp2.close ();
		return 0;

	}
}
```


----------



## sabre71789 (Sep 28, 2008)

ok, i figured out why it wasn't writing the full file, I had the files closed inside the for loop... now i have to get it to write it as a .ppm file. anyone know how this should be done?


----------



## sabre71789 (Sep 28, 2008)

ok, its actually supposed to write the bmp file as a ASCII ppm file. anyone, please help!?!?


----------



## jamiemac2005 (Jul 5, 2007)

Hey, to be honest i don't know enough C++ to help you with the programming side of this but i've done some reading on PPM files(i don't know a lot about bmp files either)... From looking at your code i think all you should have to change is the header writing functions... 

Basically a PPM file takes the format:

```
P3
#PPM File Created By Jamey first 4 lines are the header
10 10
255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255
```
where the header is the first four lines:

```
P3 (stays the same)
#PPM File Created By Jamey first 4 lines are the header (put whatever you like)
10 10 (width then height)
255 (depth)
```
followed by the rgb values for each pixel... So all you should have to do is change your header-writing functions?

Cheers,
Jamey


----------



## sabre71789 (Sep 28, 2008)

How do I get it to write that to the file?


----------



## jamiemac2005 (Jul 5, 2007)

I honestly don't know, hence why i didn't write any C++ sorry.

What's this for anyway?

Cheers,
Jamey


----------



## sabre71789 (Sep 28, 2008)

Just a stupid excorsise but my teach hasn't gotten back to me three days...


----------



## jamiemac2005 (Jul 5, 2007)

That's fair enough, if i knew how to code it i'd help but i honestly don't. Your teacher will obviously have the answer if you don't get it. I do think all you have to do is modify the header writing functions to output P3.... rather than the two bitmap headers.

Cheers,
Jamey


----------

