Write a function that reads PPM format images. A PPM image has an ASCII header f
ID: 3804132 • Letter: W
Question
Write a function that reads PPM format images. A PPM image has an ASCII header followed by binary pixel data. The header looks something like this:
P6
650 652
255
P6 is a string that indicates this is a PPM image. Most file formats start with an identifying string like this. It is called a "magic number". The next two fields are the width and height of the image. The last field gives the maximum pixel value. You can expect it will always be 255. At the end of the header is a and then the binary pixel data. The image is in color, so there are three bytes (red, green, blue) for every pixel. You should store the pixel data in a two-dimensional array ints. Each int should store the red, green, and blue bytes from on pixel. Your final program should have one function that reads a PPM image and returns a two-dimensional array of ints and the other should take a two-dimensional array of ints as an argument and write a PPM image. Your program should read an image and then write it back out to another file. Use pointer casting to turn an int into an array of four bytes. Leave one of the bytes unused. Use a separate array of bytes for I/O and copy bytes between that array and your two-dimensional array. Don't forget to delete any data you allocate on the heap.
Below are my main.cc and readWritePPM.cc files. I keep getting a seg fault. I need it fixed.
main.cc
int main() {
//char fileName[50] = "binary_pixels.txt";
char fileName[50] = "test.ppm";
int width = 0; // width of the image
int height = 0; // heigt of the image
// read the PPM file and store its contents inside an array and return the pointer to that array to pixelArray
unsigned char** pixelArray = readPPM(fileName, &width, &height);
// new line
printf(" ");
// write the PPM format images
writePPM("binaryPixel2D-Array.txt", width, height, pixelArray);
// delete memory on heap
delete [] pixelArray;
pixelArray = NULL;
} // end of main
readWritePPM.cc
unsigned char** readPPM(const char* fileName, int* width, int* height) {
// open the file to read just the header reading
FILE* fp = fopen(fileName, "rb");
// read width and height
int read = fscanf(fp, "P6 %d %d 255 ", width, height);
printf("Reading PPM file ");
// make array to store binary data
unsigned char* pixels = new unsigned char[(*width)*(*height)*3];
// read binary data
fread(pixels, sizeof(unsigned char), (*width)*(*height)*3, fp);
// use pointer casting
// create another separate array called named copy for copying the bytes from pixels array to the copy array
int size = (*width)*(*height)*4;
unsigned char* rgb = (unsigned char*) (&pixels);
unsigned char* copy = new unsigned char[size];
for(int i = 0; i < size; ++i) {
copy[i] = (int)rgb[i];
}
// Use the "Numerical Recipies trick" for storing the two-dimensional array
unsigned char** twoDarray = new unsigned char*[*height];
// copy bytes from the copy array to the flat array
*twoDarray = new unsigned char[size];
for(int i = 0; i < size; ++i) {
*twoDarray[i] = copy[i];
}
// connect each pointer in twoDarray to the start of a row in the flat array
for(int i = 1; i < *height; ++i) {
twoDarray[i] = twoDarray[i-1] + *width;
} // end of for loop
// close file
fclose(fp);
// return the array
return twoDarray;
} // end of readPPM
void writePPM(const char* fileName, int width, int height, unsigned char** pixels) {
// open file
FILE* fp = fopen(fileName, "w");
// write to a fle
printf("Writing PPM data to a file ");
fwrite(pixels, sizeof(unsigned char), width*height*4, fp);
// close file
fclose(fp);
} // end of writePPM
Explanation / Answer
main cc
char fileName[50] = "test.ppm";
char pSix[10]; // indicates this is a PPM image
int width = 0; // width of the image
int height = 0; // heigt of the image
int maximum = 0; // maximum pixel value
int size = 128; // size of the array
// read the PPM file and store its contents inside an array and return the pointer to that array to pixelArray
unsigned char* pixelArray = readPPM(fileName, pSix, &width, &height, &maximum)
read pp.cc
unsigned char* readPPM(const char* fileName, char* pSix, int* width, int* height, int* maximum) {
// open the file to read just the header reading
FILE* fr = fopen(fileName, "r");
// formatted read of header
fscanf(fr, "%s", pSix);
// check to see if it's a PPM image file
if (strncmp(pSix, "p6" , 10) != 0) {
printf("They are not the same ");
} else {
printf("They are the same ");
}
// read the rest of header
fscanf(fr, "%d %d ", width, height);
fscanf(fr, "%d ", maximum);
// check to see if they were stored properly
printf("PSix: %s ", pSix);
printf("Width: %d ", *width);
printf("Height: %d ", *height);
printf("maximum: %d ", *maximum);
//int size = width * height;
int size = 423800;
// allocate array for pixels
unsigned char* pixels = new unsigned char[size];
// unformatted read of binary pixel data
while (fread(pixels, sizeof(pixels), 128, fr)) {
printf("%s", pixels);
} // end of for loop
// close file
fclose(fr);
// return the array
return pixels;
} // end of readPPM
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.