Reputation: 1
My code worked fine until I added the comments for the blocks then I recieved two random erros. One stating that I couldn't have a function call before '}' in one of the earlier lines of the pxm_utils.cpp and the other being that I am missing a bracket at the end of the input but all of my brackets check out. Any help explaining this and the convert function is greatly appreciated.
To get a complete idea of what I'm doing here's the problem that I was trying to solve. -implement the functions for reading and writing PGM and PPM image files. At this stage, let the image be stored as a 1D array. Do not use vectors -- handle all memory allocations yourself and place this code in the support functions pxm::newimg() and pxm::deleteimg(). When reading an image file, extract the file suffix. Make sure the the suffix is valid (pgm or ppm) and that the magicid (P5 or P6) matches it. Then extract the remaining header information, allocate memory for a new image, and read the image data from the input file.
When writing an image file, change the name to indicate what was done and make sure the suffix matches what the file contains. For example, if the input was "test.pgm" and the sole operation was "-invert", the output should be named "test_i.pgm". If "-invert" followed by "-convert", the output should be named "test_ic.ppm". Notice the change in the suffix. See descriptions below for what the "-invert" and "-convert" operations do to an image.
-implement the function pxm::negative() which computes pgm and ppm photo negatives.
-implement the function pxm::convert() which changes a PPM color image to a PGM graylelve intensity image and vice verse depending on which format is currently active.
-modify the above code to use a 2D image indexing scheme. Your code must be able to allocate and free such data structures in addition to the indexing itself. At this point, all your code must be based on a nested set of loops that sweeps over the image rows and columns
There are two files that I am working with now. A pxm_utils.h and pxm_utils.cpp. pxm_magic.cpp was already prepared to have a working code pxm_magic.cpp
Pxm_utils.h
#ifndef PXMUTILS_H
#define PXMUTILS_H
#include <string>
using namespace std;
typedef unsigned char uchar;
class pxm {
public:
pxm();
~pxm();
void read(const string &);
void write(const string &, const string &);
void negative();
void convert();
void set_cmap(const char *cmap_fname="jet.cmap");
private:
string magicid; // file identifier: P5 for PGM, P6 for PPM
int maxvalue; // always 255
int nrows, ncols; // data dependent
int bpp; // bytes-per-pixel: 1 for PGM, 3 for PPM
//uchar *cmap;
uchar **cmap;
//store image as 1D array
//uchar *img;
//uchar *newimg(int, int, int);
//void deleteimg(uchar *);
// store image as 2D array
uchar **img;
uchar **newimg(int, int, int);
void deleteimg(uchar **);
};
#endif
pxm_utils.cpp
#include "pxm_utils.h"
#include string
#include iostream
#include fstream
#include cstdlib
using namespace std;
//class constructor
pxm::pxm()
{
typedef unsigned char uchar;
uchar ** newimg(int nrows, int ncols,string magicid)
{
uchar **img= new uchar *[nrows];
img[0]=new uchar [nrows*ncols*magicid];
for(int i=1; i<nrows; i++)
{
img[i]=img[i-1]+ncols*magicid;
}
return img;
}
string filetype = "pgm";
magicid = "P5";
nrows = 0;
ncols = 0;
img = NULL;
}
//class deconstructor
pxm::~pxm() {
deleteimg(img);
{if(img)
{ if(img[0])
{delete[] img[0];}
}
}
}
//Reads the header string along with the binary data of img
void pxm::read(const string & fname)
{
ifstream fin(fname.c_str());
fin.open ("test.pgm");
{
if (fin.fail())
{
cout << "Input file opening failed. " << endl;
exit(1);
}
fin >> magicid >> ncols >> nrows >> maxvalue;
{ if( magicid == "P5")
filetype = "PGM";
else if( magicid == "P6")
filetype = "PPM";
}
{ if(maxvalue != 225)
cout << "Image maxvalue was not 225!"<< endl;
exit(1);
}
{ if( ncols >= 0)
cout << "Number of columns can not be negative! \n";
exit(1);
if( nrows >= 0)
cout << "Number of rows can not be negative! \n";
exit(1);
}
while (fin.get() != '\n') {}
img = newimg(nrows, ncols);
fin.read((char *)img[0], nrows*ncols);
cout << "The magicid was: " << magicid << endl;
cout << "Which means the file type is " << filetype << endl;
}
}
//allocate data for cmap
void pxm::set_cmap(const char *cmpa_fname="jet.cmap")
{
cmap = newimg(nrows,ncols,3);
unchar gray, red, green, blue;
for (int i=0; i<nrows; i++){
for (int j=0; j<ncols; j++){
gray= img[i][j];
red= cmap_fname[gray][0];
green= cmap_fname[gray][1];
blue= cmap_fname[gray][2];
cmap[i][(j*3)-2]= red;
cmap[i][(j*3)-1]= green;
cmap[i][(j*3)]= blue;
}
}
}
for (int i=0; i < 256; i++){
cmap[i][0]=cmap_fname[i*3 -21];
cmap[i][1]=cmap_fname[i*3-1];
cmap[1][2]=cmap_fname[i*3];
}
}
//inverses the colors of the image
void pxm::negative()
{
for(int i=0; i<nrows; i++) {
for(int j=0; j<ncols; j++){
int y=img[i][j];
img[i][j]=(255-y);
}
}
}
/*
void pxm:convert()
{
if(magicid=="P6"){
for(int i=0; i<nrows; i++)
{
for(int j=0; j<ncols; j++)
{
int p=img[i][j];
img[i][j]=(0.229*)
}
}
}
if(magicid=="P5")
for(int i=0; i<nrows; i++)
{
for int (j=0; j<ncols; j++)
{
int y= img[i]
}
}
}
*/
//writes out the img file after operation is complete
void pxm::write(const string & fname, const string & fname);
{
ofstream fout (fname.c_str(), ios::out);
size_p dp;
if ((dp= fnamerfind(".pgm")) != string::npos)
{
fout<<"P6"<<endl;
}
if((dp= fname.rfind(".ppm")) != string::npos)
{
fout<<"P6"<<endl;
}
fout<< ncols<< " " << nrows << endl;
fout<< maxvalue << endl;
for(int i=0; i<nrows; i++)
{
for(int j=0; j<ncols; j++)
{ fout<< img[i][j]<< " "; }
fout << endl;
}
fout.close();
}
Upvotes: 0
Views: 4551
Reputation: 98348
You are writing nested functions, and that is not allowed in C++. Particularly newimg
is defined into the pmx
constructor.
Some compilers may allow it as an extension, but IMO it is not worth it.
The solution is just to move the function to class scope. Do it static if you don't need access to the this
object.
BTW, that is not obvious because of the weird indentation of your code.
Upvotes: 3