Any help would be appreciated, this project is fustrating me. Has to do with PGM image files, but really the problem in my code (I would assume, lies within my pointers and dynamically allocating memory).
Any help would be appreciated.
Code:
(main.cpp)
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
#include "pgm.h"
int main(int argc, char *argv[])
{
cout << "number of command line parameters: "<<argc<<endl;
for (int i=0;i<argc;i++)
{
cout << i << ' ' << argv[i] << endl;
}
// here's how to put them into strings:
string words[10];
for (int i=0;i<min(10, argc); i++)
words[i] = argv[i];
cout << "the command line was:"<<endl;
for (int i=0;i<min(10, argc); i++)
cout << words[i]<<' ';
cout << endl<<endl;
string raw, dark, flat, outname;
PGM r;
PGM d;
PGM f;
PGM final;
PGM lin;
PGM log;
cout << "raw? " << endl;
getline(cin, raw);
cout << "dark? " << endl;
getline(cin, dark);
cout << "flat? " << endl;
getline(cin, flat);
cout << "outputname?" << endl;
getline(cin, outname);
try
{
//read each file, return error if dont exsist.
cout << "Reading files..." << endl;
readPGM(raw, r);
cout << "Raw Read" << endl;
readPGM(dark, d);
cout << "Dark Read" << endl;
readPGM(flat, f);
cout << "Flat Read" << endl;
cout << endl << "Processing Final Image..." << endl;
processPGM(r, d, f, final);
dividePGM(final, d);
cout << "File Processed" << endl;
cout << "Scaleing Final Image..." << endl;
//stupid function to get mv
double mv = getMV(r);
//Scale final image linearly
cout << "Stretching linear..." << endl;
stretch(final, lin, 0, mv, 0, 255);
cout << "Writing linear..." << endl;
writePGM(outname, lin);
//Scale final image log
cout << "Stretching log..." << endl;
stretch(final, log, 0, mv, 0, 255, LOGSCALE);
cout << "Writing log..." << endl;
writePGM(outname, log);
}
catch (string e)
{
cout << "Problem: "<<e<<endl;
}
#ifdef WIN32
system("PAUSE");
#endif
return EXIT_SUCCESS;
}
(pgm.h)
#ifndef _SAMPLE_PGM_H_
#define _SAMPLE_PGM_H_
// this should all be in a namespace!
struct PGM
{
double *pix;
int nc;
int nr;
string type;
string comments;
double mv;
//PGM();
//PGM(int size, int initval=0);
};
void readPGM(string filename, PGM &);
void writePGM(string filename, PGM &);
void stretch(PGM &sf, PGM &sl, double in_min, double in_max, double out_min, double out_max,
bool do_logscale = false);
void processPGM(PGM r, PGM d, PGM f, PGM &final);
void dividePGM(PGM &final, PGM d);
double getMV(PGM &r);
enum STUFF{LINEAR=false, LOGSCALE=true};
#endif
(pgm.cpp)
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <cmath>
using namespace std;
#include "pgm.h"
#define ALLOW_COMMENTS
void writePGM(string filename, PGM &w)
{
if (w.type != "P2" && w.type != "P5") throw string("writePGM: error: invalid type: "+w.type);
if (w.type == "P5")
throw string("writePGM: sorry. cannot write out P5 PGMs yet. please write this for me.");
ofstream o(filename.c_str());
if (!o) throw string("writePGM: error: cannot open file for writing: "+filename);
o << w.type << " " << w.nc << " " << w.nr << " ";
if (w.comments.size()>0) o << endl<<w.comments;
if (w.comments[w.comments.size()-1] != '\n' && w.comments[w.comments.size()-1] != '\r') o <<endl;
o << static_cast<int>(w.mv)<<endl;
int i=0; // # of elements output on this line so far.
for (int r=0;r<w.nr;r++)
{
for (int c=0;c<w.nc;c++)
{
o << setw(3) << static_cast<int>(w.pix[r*w.nc+c]);
if (i%16==15) o << endl;
else o << ' ';
}
o << endl;
i=0;
}
}
//......................................:................................
void stretch(PGM &sf, PGM &sl, double in_min, double in_max, double out_min, double out_max,
bool do_logscale) // note: default value for do_logscale is given only in the prototype. Not here.
{
double pv;
sl.type = sf.type;
sl.comments = sf.comments;
sl.nc = sf.nc;
sl.nr = sf.nr;
double maxout = out_min; // keeps track of max output value.
if (sf.nr == 0 || sf.nc == 0) return;
if (!do_logscale)
{
for(int r=0;r<sf.nr;r++)
{
for(int c=0;c<sf.nc;c++)
{
int ix = r*sf.nc+c;
pv = sf.pix[ix];
if (pv < in_min)
sl.pix[ix] = out_min;
else if (pv <= in_max)
{
sl.pix[ix] = out_min + (pv-in_min)/(in_max - in_min)*(out_max-out_min);
}
else
sl.pix[ix] = out_max;
maxout = max(maxout, sl.pix[ix]);
}
}
}
else
{
double maxval, val;
maxval = log(1+in_max-in_min);
for(int r=0;r<sf.nr;r++)
{
for(int c=0;c<sf.nc;c++)
{
int ix = r*sf.nc+c;
pv = sf.pix[ix];
if (pv < in_min)
sl.pix[ix] = out_min;
else if (pv <= in_max)
{
val = log(1+ pv - in_min);
sl.pix[ix] = out_min + (val/maxval)*(out_max-out_min);
}
else
sl.pix[ix] = out_max;
maxout = max(maxout, sl.pix[ix]);
}
}
}
sl.mv = static_cast<int>(maxout);
}
void processPGM(PGM r, PGM d, PGM f, PGM &final)
{
final.type = r.type;
final.comments = r.comments;
final.nc = r.nc;
final.nr = r.nr;
final.mv = r.mv;
final.pix = new double[r.nc*r.nr];
cout << r.nc;
for(int i=0;i<r.nc*r.nr;i++)
{
final.pix[i] = (r.pix[i] - d.pix[i]);
}
}
void dividePGM(PGM &final, PGM f)
{
cout << "Divideing..." << endl;
for(int i=0;i<f.nc*f.nr;i++)
{ final.pix[i] = (final.pix[i] / f.pix[i]);
cout << final.pix[i] << " ";
}
delete [] final.pix;
}
double getMV(PGM &r)
{
return r.mv;
}
#ifdef ALLOW_COMMENTS
void readPGM(string filename, PGM &v)
{
bool got_nr = false, got_nc = false, got_maxval = false;
string ty, cmnt;
double val;
int ival;
char ch;
v.pix = new double[v.nc*v.nr];
//double pix[v.nc*v.nr];
// v.pix = pix;
ifstream s(filename.c_str(), ios::in | ios::binary); // you can still use >> on binary files. it just doesn't translate newlines into newline/returns
if (!s) throw string("readPGM: error: cannot open file " + filename);
s >> ty;
if (ty != "P2" && ty != "P5")
throw string("readPGM: error: not a PGM: " + ty);
// this rather awkward code is necessary to get around the possibility
// of comments after the magic number and before the nr, nc & maxvals.
while (!got_maxval)
{
ch = s.get();
if (isspace(ch)) continue;
else if (ch == '#')
{
getline(s, cmnt);
v.comments += "#"+cmnt+'\n';
}
else
{
s.putback(ch);
s >> val;
if (!got_nc)
{
got_nc = true;
v.nc = static_cast<int>(val);
}
else if (!got_nr)
{
got_nr = true;
v.nr = static_cast<int>(val);
}
else if (!got_maxval)
{
v.mv = val;
got_maxval = true;
}
}
if (!s)
throw string("readPGM: error reading pgm header from "+filename);
}
s.get(); // skip over white space after maxval
v.type = ty;
if (v.type== "P5")
{
s.read(reinterpret_cast<char*>(v.pix),sizeof(v.nc*v.nr));
//if(!s)
// throw string("readPGM: P5 code dont work yet. please write this code for me.");
}
else // type is P2
{
for (int i=0;i<v.nc*v.nr;i++)
{
s >> ival; // read in an integer value
v.pix[i] = ival; // save it in the pixel array, which is double.
}
if (!s)
throw string("writePGM: error reading array portion of pgm file.");
}
delete [] v.pix;
}
#endif
Please help me get this working!