Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

here is the program to be modified: http://pastebin.com/vwzBykzM Next, add the f

ID: 3545409 • Letter: H

Question

here is the program to be modified: http://pastebin.com/vwzBykzM



Next, add the following ppmCopy2D function to your program. This is nearly identical to the existing ppmCopy function, except for using a 2D array and the new functions ppmReadImage and ppmWriteImage:


//

// ppmCopy2D:

//

// Copies an image in PPM format from the source file

// to the destination file, using a 2D array.

//

void ppmCopy2D(int image[MAXROWS][MAXCOLS], string srcFilename, string destFilename)

{

ifstream infile;

ofstream outfile;

string magicNumber;

int numCols, numRows, maxColor;

// open the files:

infile.open( srcFilename.c_str() );

if (!infile.good())

{

cout << "**ERROR in ppmCopy: unable to open input file!" << endl;

exit(-1);

}

outfile.open( destFilename.c_str() );

if (!outfile.good())


{

cout << "**ERROR in ppmCopy: unable to open output file!" << endl;

exit(-1);

}

// read header from input file:

infile >> magicNumber;

infile >> numCols;

infile >> numRows;

infile >> maxColor;

// now write header to output file:

outfile << magicNumber << endl;

outfile << numCols << " " << numRows << endl;

outfile << maxColor << endl;

// now read the image and then write it:

ppmReadImage(image, infile, numRows, numCols);

ppmWriteImage(image, outfile, numRows, numCols);

// done, must close the files for changes to be saved:

infile.close();

outfile.close();


}





Here are the definitions of the ppmReadImage and ppmWriteImage functions:

//

// ppmReadImage:

//

// Reads an image from the given file and into the provided 2D array.

//

void ppmReadImage(int image[MAXROWS][MAXCOLS], ifstream& infile, int numRows, int numCols)

{

// TODO!

}

//

// ppmWriteImage:

//

// Writes an image from provided 2D array to the given file.

//

void ppmWriteImage(int image[MAXROWS][MAXCOLS], ofstream& outfile, int numRows, int numCols)

{

// TODO!

}

Notice that all three of these functions are passed the 2D array to work with. The last step is to modify yourmain()function to call

Explanation / Answer

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

//
// Constants:
//
// MAXHEIGHT: max height of an image (# pixels in a column)
// MAXWIDTH:   max width of an image (# pixels in a row)
// MAXCOLS:    max # of RGB values in a row
// MAXROWS:    max # of rows
//
#define MAXHEIGHT 5000
#define MAXWIDTH 5000
#define MAXCOLS   (3*MAXWIDTH)
#define MAXROWS   (MAXHEIGHT)


//
// ppmReadRow:
//
// Reads one row of the image from the input file into the row array;
// numCols is # of pixels in that row.
//
void ppmReadRow(ifstream& infile, int row[MAXCOLS], int numCols)
{
    int N;

    N = 3 * numCols; // there are 3 RGB values per column:

    for (int i = 0; i < N; i++) // for each RGB value:
    {
        infile >> row[i];
    }
}


//
// ppmWriteRow:
//
// Writes one row of the image from the row array to the output file;
// numCols is # of pixels in that row.
//
void ppmWriteRow(ofstream& outfile, int row[MAXCOLS], int numCols)
{
    int N;

    N = 3 * numCols; // there are 3 RGB values per column:

    for (int i = 0; i < N; i++) // for each RGB value:
    {
        outfile << row[i] << " ";
    }

    outfile << endl; // each row on a line by itself:
}


//
// ppmCopy:
//
// Copies an image in PPM format from the source file
// to the destination file.
//
void ppmCopy(string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;
    int numCols, numRows, maxColor;
    int row[MAXCOLS];

    // open the files:
    infile.open( srcFilename.c_str() );
    if (!infile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );
    if (!outfile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the rows of the image, one by one, and
    // write to the output file:
    for (int r = 0; r < numRows; r++)
    {
        ppmReadRow(infile, row, numCols);
        ppmWriteRow(outfile, row, numCols);
    }

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}


//
// ppmGrayscaleRow:
//
// Converts the given row of pixels to grayscale, updating the
// pixels values in place.
//
void ppmGrayscaleRow(int row[MAXCOLS], int numCols)
{
    int N, sum, avg;

    N = 3 * numCols; // there are 3 RGB values per column:

    //
    // for each pixel, average the RGB values and write the
    // average back as the new RGB values:
    //
    for (int i = 0; i < N; i = i+3 /*next pixel*/)
    {
        sum = row[i]+row[i+1]+row[i+2];

        avg = sum / 3;

        row[i] = avg;
        row[i+1] = avg;
        row[i+2] = avg;
    }
}


//
// ppmGrayscale:
//
// Converts the given image file to grayscale, and writes the new
// "gray" image to the destination file.
//
void ppmGrayscale(string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;
    int numCols, numRows, maxColor;
    int row[MAXCOLS];

    // open the files:
    infile.open( srcFilename.c_str() );
    if (!infile.good())
    {
        cout << "**ERROR in ppmGrayscale: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );
    if (!outfile.good())
    {
        cout << "**ERROR in ppmGrayscale: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the rows of the image, one by one, gray scale
    // that row, and write to the output file:
    for (int r = 0; r < numRows; r++)
    {
        ppmReadRow(infile, row, numCols);
        ppmGrayscaleRow(row, numCols);
        ppmWriteRow(outfile, row, numCols);
    }

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}


//
// ppmFlipRowHorizontally:
//
// Flips the given row of pixels horizontally --- i.e. the pixels on the
// left move to the right, and the pixels on the right move to the left.
//
void ppmFlipRowHorizontally(int row[MAXCOLS], int numCols)
{
    int N, L, R, temp;

    N = 3 * numCols; // there are 3 RGB values per column:

    L = 0;      // index of left-most pixel:
    R = N - 3; // index of right-most pixel:

    //
    // The idea is to keep 2 indices, L and R, which stand for
    // Left and Right. The left index goes left to right, and
    // the right index goes right to left. We swap the pixel
    // @ L with the pixel @ R, and repeat until the indices
    // cross each other:
    //
    while (L < R) // still pixels on the left and right:
    {
        // swap red:
        temp = row[L];
        row[L] = row[R];
        row[R] = temp;

        L++; // advance to green:
        R++;

        // swap green:
        temp = row[L];
        row[L] = row[R];
        row[R] = temp;

        L++; // advance to blue:
        R++;

        // swap blue:
        temp = row[L];
        row[L] = row[R];
        row[R] = temp;

        // now advance L to start of next pixel on the right:
        L = L + 1;

        // and reduce R to start of next pixel on the left:
        R = R - 2; // subtract the +2 we did above:
        R = R - 3; // subtract 3 to get to start of pixel:
    }
}


//
// ppmFlipHorizontally:
//
// Flips the given image horizontally --- pixels on left go to the right,
// and pixels on the right go to the left --- and writes the new image to
// destination file.
//
void ppmFlipHorizontally(string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;
    int numCols, numRows, maxColor;
    int row[MAXCOLS];

    // open the files:
    infile.open( srcFilename.c_str() );
    if (!infile.good())
    {
        cout << "**ERROR in ppmFlipHorizontally: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );
    if (!outfile.good())
    {
        cout << "**ERROR in ppmFlipHorizontally: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the rows of the image, one by one, and flip each
    // row horizontally, then write to the output file:
    for (int r = 0; r < numRows; r++)
    {
        ppmReadRow(infile, row, numCols);
        ppmFlipRowHorizontally(row, numCols);
        ppmWriteRow(outfile, row, numCols);
    }

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}


//
// ppmExtremeContrastRow:
//
// Converts the given row of pixels to grayscale, updating the
// pixels values in place.
//
void ppmExtremeContrastRow(int row[MAXCOLS], int numCols, int maxColor)
{
    int N, midpoint;

    N = 3 * numCols; // there are 3 RGB values per column:

    midpoint = maxColor / 2;

    //
    // for each RGB value, compare to midpoint of color range, and
    // then change to extreme ends --- either 0 or maxColor:
    //
    for (int i = 0; i < N; i++)
    {
        if (row[i] > midpoint)
            row[i] = maxColor;
        else
            row[i] = 0;
    }
}


//
// ppmExtremeContrast:
//
// Converts each pixel to either 0 or max color value, creating an
// extremely contrasty picture.
//
void ppmExtremeContrast(string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;
    int numCols, numRows, maxColor;
    int row[MAXCOLS];

    // open the files:
    infile.open( srcFilename.c_str() );
    if (!infile.good())
    {
        cout << "**ERROR in ppmExtremeContrast: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );
    if (!outfile.good())
    {
        cout << "**ERROR in ppmExtremeContrast: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the rows of the image, one by one, and flip each
    // row horizontally, then write to the output file:
    for (int r = 0; r < numRows; r++)
    {
        ppmReadRow(infile, row, numCols);
        ppmExtremeContrastRow(row, numCols, maxColor);
        ppmWriteRow(outfile, row, numCols);
    }

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}

int gImage[MAXROWS][MAXCOLS]; //global image as 2D array

//
// ppmReadImage:
//
// Reads an image from the given file and into the provided 2D array.
//

void ppmReadImage(int image[MAXROWS][MAXCOLS], ifstream& infile, int numRows, int numCols)
{
    int N;

    N = 3 * numCols; // there are 3 RGB values per column:

    for(int i = 0; i < numRows; i++)
    {
        for (int j = 0; j < N; j++) // for each RGB value:
        {
            infile >> image[i][j];
        }
    }
}

//
// ppmWriteImage:
//
// Writes an image from provided 2D array to the given file.
//
void ppmWriteImage(int image[MAXROWS][MAXCOLS], ofstream& outfile, int numRows, int numCols)
{
    int N;

    N = 3 * numCols; // there are 3 RGB values per column:

    for (int i = 0; i < numRows; i++) // for each RGB value:
    {
        for (int j = 0; j < N; j++) // for each RGB value:
        {
            outfile << image[i][j] << " ";
        }
    }

    outfile << endl; // each row on a line by itself:
}

//
// ppmCopy2D:
//
// Copies an image in PPM format from the source file
// to the destination file, using a 2D array.
//
void ppmCopy2D(int image[MAXROWS][MAXCOLS], string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;

    int numCols, numRows, maxColor;

    // open the files:
    infile.open( srcFilename.c_str() );

    if (!infile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );

    if (!outfile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the image and then write it:
    ppmReadImage(image, infile, numRows, numCols);
    ppmWriteImage(image, outfile, numRows, numCols);

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}

//
// InverColors:
//
// Copies an image in PPM format from the source file
// to the destination file, using a 2D array, while inverting its colors.
//
void invertColors(int image[MAXROWS][MAXCOLS], string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;

    int numCols, numRows, maxColor;

    // open the files:
    infile.open( srcFilename.c_str() );

    if (!infile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );

    if (!outfile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the image and then write it:
    ppmReadImage(image, infile, numRows, numCols);

    int N = 3 * numCols;

    for (int i = 0; i < numRows; i++) // for each RGB value:
    {
        for (int j = 0; j < N; j++) // for each RGB value:
        {
            image[i][j] = maxColor - image[i][j];
        }
    }

    ppmWriteImage(image, outfile, numRows, numCols);

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}

//
// Flip Image Vertical:
//
// Copies an image in PPM format from the source file
// to the destination file, using a 2D array, while flipping the image vertically.
//
void flipImageVertical(int image[MAXROWS][MAXCOLS], string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;

    int numCols, numRows, maxColor;

    // open the files:
    infile.open( srcFilename.c_str() );

    if (!infile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );

    if (!outfile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the image and then write it:
    ppmReadImage(image, infile, numRows, numCols);

    int N = 3 * numCols;
    int tempvalue;

    for (int i = 0; i < numRows/2; i++) // for each RGB value:
    {
        for (int j = 0; j < N; j++) // for each RGB value:
        {
            tempvalue = image[i][j];
            image[i][j] = image[numRows - i][j];
            image[numRows - i][j] = tempvalue;
        }
    }

    ppmWriteImage(image, outfile, numRows, numCols);

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}

//
// Make Image Darker:
//
// Copies an image in PPM format from the source file
// to the destination file, using a 2D array, while darkening the image.
//
void makeImageDarker(int image[MAXROWS][MAXCOLS], string srcFilename, string destFilename)
{
    ifstream infile;
    ofstream outfile;
    string magicNumber;

    int numCols, numRows, maxColor;

    // open the files:
    infile.open( srcFilename.c_str() );

    if (!infile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open input file!" << endl;
        exit(-1);
    }

    outfile.open( destFilename.c_str() );

    if (!outfile.good())
    {
        cout << "**ERROR in ppmCopy: unable to open output file!" << endl;
        exit(-1);
    }

    // read header from input file:
    infile >> magicNumber;
    infile >> numCols;
    infile >> numRows;
    infile >> maxColor;

    // now write header to output file:
    outfile << magicNumber << endl;
    outfile << numCols << " " << numRows << endl;
    outfile << maxColor << endl;

    // now read the image and then write it:
    ppmReadImage(image, infile, numRows, numCols);

    int N = 3 * numCols;

    for (int i = 0; i < numRows/2; i++) // for each RGB value:
    {
        for (int j = 0; j < N; j++) // for each RGB value:
        {
            image[i][j] = image[i][j] - 25;
            if(image[i][j] < 0)
            {
                image[i][j] = 0;
            }
        }
    }

    ppmWriteImage(image, outfile, numRows, numCols);

    // done, must close the files for changes to be saved:
    infile.close();
    outfile.close();
}


//
// main:
//
int main()
{
    string srcFile;
    string destFile;
    int operation;

    cout << "** PPM (Portable PixMap) Image Editor **" << endl;
    cout << endl;

    while(1)
    {

    operation = 10;

    while(operation < 0 || operation > 8)
    {
    //
    // present menu of choices to user:
    //

        cout << endl;
        cout << "What operation would you like to perform?" << endl;
        cout << " 0. Exit" << endl;
        cout << " 1. Copy" << endl;
        cout << " 2. Grayscale conversion" << endl;
        cout << " 3. Flip horizontally" << endl;
        cout << " 4. Extreme contrast" << endl;
        cout << " 5. Copy 2D" << endl;
        cout << " 6. Invert Colors" << endl;
        cout << " 7. Flip Image Vertically" << endl;
        cout << " 8. Make Image Darker" << endl;
        cout << endl;

        cout << "Enter the operation 0 - 8: ";
        cin >> operation;

        if(operation < 0 || operation > 8)
        {
            cout << "**ERROR: unknown operation" << endl;
        }
    }

    if(operation != 0)
    {
        //
        // input file names: source and destination:
        //
        cout << "Enter input filename: ";
        cin >> srcFile;

        cout << "Enter output filename: ";
        cin >> destFile;

        //
        // perform operation selected by user:
        //
    }


    if(operation == 0)
    {
        cout << endl;
        cout << "** Done **" << endl;
        cout << endl;
        return 0;
    }
    else if (operation == 1)
    {
        cout << "copying..." << endl;
        ppmCopy(srcFile, destFile);
    }
    else if (operation == 2)
    {
        cout << "converting to grayscale..." << endl;
        ppmGrayscale(srcFile, destFile);
    }
    else if (operation == 3)
    {
        cout << "flipping..." << endl;
        ppmFlipHorizontally(srcFile, destFile);
    }
    else if (operation == 4)
    {
        cout << "converting to extreme contrast..." << endl;
        ppmExtremeContrast(srcFile, destFile);
    }
    else if (operation == 5)
    {
        cout << "2D copying..." << endl;
        ppmCopy2D(gImage, srcFile, destFile);
    }
    else if (operation == 6)
    {
        cout << "Inverting colors..." << endl;
        invertColors(gImage, srcFile, destFile);
    }
    else if (operation == 7)
    {
        cout << "Flipping image vertically..." << endl;
        flipImageVertical(gImage, srcFile, destFile);
    }
    else if (operation == 8)
    {
        cout << "Make Image Darker" << endl;
        makeImageDarker(gImage, srcFile, destFile);
    }

    }

    return 0;
}




The changes and modifications mentioned in the problem statement have been made. For the operation of our own choice, I created an operation that will make the image darker.

Hope this helps you. If you have any query, just leave a comment.
Cheers!