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!
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.