I have a BMP file. I want to read all of its characters and rotate 90 cw the picture by these codes. But this codes works only on small pictures and colors were changed. I want use this codes for 800*686 pixels picture. this codes doesn't work for it. I think error is in reading file, because when I check the char vector of input file, after 59000 bytes, all of the chars in vector filled by 0 and the file didn't read compeletely:
struct pixel
{ char blue;
char green;
char red;
};
int _tmain(int argc, _TCHAR* argv[])
{
//Reading file and save all into data vector
fstream fl("d://b.bmp");
ofstream fl2("d://b2.bmp");
fl.seekg(0,std::ios::end);
streampos length = fl.tellg();
vector<char> data(length);
fl.seekg(0,ios::beg);
fl.read(&data[0],length);
//make a string of bytes based on characters in "file" vector ,to calculate file features
byte intfile[54];
for(int i=0;i<54;i++)
{
if (data[i]<0)
intfile[i]=(256+data[i]);
else
intfile[i]=data[i];
}
//bpp is 2 bytes on 28,29 characters
short int bpp = intfile[28] | intfile[29] << 8;
//size of file is 4 bytes on 2,3,4,5 characters
unsigned int size= intfile[2] | intfile[3] << 8 | intfile[4] << 16 | intfile[5] << 24;
//offset of pixeles array is 4 bytes on 10,11,12,13 characters
unsigned int offset= intfile[10] | intfile[11] << 8 | intfile[12] << 16 | intfile[13] << 24;
//with is 4 bytes on 18,19,20,21 characters
unsigned int with= intfile[18] | intfile[19] << 8 | intfile[20] << 16 | intfile[21] << 24;
//height is 4 bytes on 22,23,24,25 characters
unsigned int height= intfile[22] | intfile[23] << 8 | intfile[24] << 16 | intfile[25] << 24;
//format of compression is 4 bytes on 30,31,32,33 characters
unsigned int format= intfile[30] | intfile[31] << 8 | intfile[32] << 16 | intfile[33] << 24;
//2D vector of pixels and filling it by data vector
vector< vector<pixel> > arrpix;
arrpix.resize(height);
for(int j=0;j<height;j++)
arrpix[j].resize(with);
int ix=offset;
for(int i=0;i<height;i++){
for(int j=0;j<with;j++){
arrpix[i][j].blue=data[ix++];
arrpix[i][j].green=data[ix++];
arrpix[i][j].red=data[ix++];
}
ix+=2;//padd
}
//2d new vector for making new rotated file
vector< vector<pixel> > arrpix2;
arrpix2.resize(with);
for(int j=0;j<with;j++)
arrpix2[j].resize(height);
for(int i=0;i<with;i++)
for(int j=0;j<height;j++){
arrpix2[i][j].blue=arrpix[j][with-1-i].blue;
arrpix2[i][j].green=arrpix[j][with-1-i].green;
arrpix2[i][j].red=arrpix[j][with-1-i].red;
}
//newsize
unsigned int news=(with*height*3)+54;//in rotation pad is not need because the new with is 800
//makeing new vector
vector<char> data2(news);
for(int i=0;i<news;i++)
data2[i]=data[i];
//change size
data2[5] = (news >> 24) & 0xFF;
data2[4] = (news >> 16) & 0xFF;
data2[3] = (news >> 8) & 0xFF;
data2[2] = news & 0xFF;
//replace height and with
for(int i=0;i<4;i++){
data2[18+i]=data[22+i];
data2[22+i]=data[18+i];}
ix=offset;
//filling data by 2d new vector
for(int i=0;i<with;i++){
for(int j=0;j<height;j++){
data2[ix++]=arrpix2[i][j].blue;
data2[ix++]=arrpix2[i][j].green;
data2[ix++]=arrpix2[i][j].red;
}
}
fl2.write(&data2[0],news);
fl2.seekp(news,ios::beg);
fl2.close();
return 0;
}
When you reposition the file back to the beginning, to actually read the data I think you want:
fl.seekg(0,ios::beg);
rather than
fl.seekg(length,ios::beg);
edit:
After the read add this code:
if(f1.eof())
{
std::cerr << "Error reading file."
<< " Requested " << length << " bytes."
<< " Read " << f1.gcount() << bytes."
<< std::endl;
}
That should tell you how big your code thinks the file is (verify against actual file size), and whether f1 thinks the read went well.
Also you should open the file in binary mode by using the ios::binary mode flag when you open the file.