Write a program in C for the following: Problem Statement Color is produced in c
ID: 3687667 • Letter: W
Question
Write a program in C for the following:
Problem Statement
Color is produced in computer monitors using the RGB color model. In this model, a color is formed by superimposing light from three different color beams (red, green, blue) with arbitrary intensity from fully off to fully on. Color images are described as a rectangular grid of pixels, each of which has a red component, a green component and a blue component. Pixel values often are written as a triple (r, g, b). The maximum component value depends on the number of bytes used store the component values. One common scheme is to use one byte to store a component value, resulting in values in the range 0 (fully off) to 255 (fully on). For example, in this scheme, a pixel of pure red color would have value (255, 0, 0).
Most image formats are binary formats that arrange the pixel components in various ways, usually to compress the data. However, there is an ASCII format that we can read and write using regular C language file scanning and printing routines called the Portable Pix Map (or PPM) format. In this format, the above image is represented as follows:
P3
320 180
255
255 0 0
255 0 0
255 0 0
...
The first three lines are a "header" describing the characteristics of the image. The "P3" is a "magic" string that must be the first line of the file and tells programs this is a file containing a single, color PPM image. The second line is the width (number of columns) and height (number of rows), respectively, of the image in pixels. The third line is the maximum possible color value in the file, usually 255, but not always. The lines after this are the RGB values for each pixel in the image starting with the upper left corner going left to right and top to bottom. (The first pixels of the image above are all red.) Note that while this format is easy for humans to read, it is very inefficient in space. This image is around 0.5 megabytes in PPM format, while the equivalent GIF format file is only about 655 bytes. PPM files can be viewed using various image viewers. For Windows, a commonly used one is called IrfanView, which is available for noncommercial use at http://www.irfanview.com/. IrfanView is available in the CECS labs. A link to the IrfanView website where it can be downloaded is available at the course webpage.
Assignment
The assignment for this project is to read a PPM image from a file into a twodimensional array of pixels, apply one of several possible transformations by the user, then write the new image out to a file in PPM format. (I.e., the program is to do only one transformation to one image.) The possible transformations are
• flip horizontal: flip the image along the yaxis so that the first column is the last column, etc.
• flip vertical: flip the image along the xaxis so that the first row is the last row, etc.
• rotate left: rotate the image to the left 90 degrees so that the first row is the first column with the first pixel being at the bottomleft
• rotate right: rotate the image to the right 90 degrees so that the first row is the last column with the first pixel at the upperright
Design Criteria
Your program must conform to the following design criteria in order to earn full credit.
A pixel type must be defined as follows. The structure definitions and function prototypes must be stored in a file named pixel.h. The function definitions must be stored in a file named pixel.c. The names of these files must not be different. Submissions that do not provide these files will not compile in the submission system.
• A pixel_t structure type must be defined with integer components named red, green, and blue that is used to represent one pixel of an image.
• There must be a function read_pixel_from_file that receives a file pointer that is connected to a file that is opened for reading and reads three integers (the RGB values) for a pixel. It must either return or pass back (your choice) a pixel object with the read in RGB values for its components.
• There must be a function write_pixel_from_file that receives a file pointer that is connected to a file that is opened for writing and a pixel. It writes the RGB component values of the pixel to the file in the format given below.
The rest of the program must be in a file named main.c as usual, and must meet the following specifications.
• An image must be stored in a twodimensional array of pixel_t structures. You may assume that an image will be no larger than 500 by 500 pixels.
• There must be a function open_file that receives a prompt string and a file mode string (i.e. the argument will be either "r" or "w"), and returns a file pointer to an open file. The function should prompt the user for a filename using the prompt string, and attempt to open it using the mode string ("r" for read, "w" for write). If the attempt to open fails, the function should display an error message as shown below and end the program using exit(1). (I.e. there is no looping for a new filename.)
• There must be a function read_ppm_image that passes back a twodimensional array of pixel_t structures that will store the pixels of an image read from a file, and also passes back the width (number of columns), height (number of rows), and maximum color value of the image. The function should open the file (using the open_file function) and read the header information. If the magic string is not present, an error message as shown below should be displayed and the program should exit using exit(1). Otherwise the function should read the pixel information into the array using the pixel type read function.
• There must a function write_ppm_image that receives a twodimensional array of pixel_t structures that store the pixels of an image, the width (number of columns), the height (number of rows), and the maximum color value of the image. The function should open the file (using the open_file function), write the header information, then write the pixel information from the array using the pixel type write function.
• There must one function for each transformation choice (flip_horizontal, flip_vertical, rotate_left, rotate_right) that receives a twodimensional array of pixel_t structures that store the pixels in the image, and passes back a (separate) two dimensional array of pixel_t structures that is the transformation of the received image. These functions also receive the width (number of columns), and the height (number of rows) of the received image.
• Of course, use of additional functions where appropriate is encouraged.
The output of the program must conform to the following several examples (user input in bold).
PPM Image Manipulator
Enter the name of a PPM image file: primary.ppm
Available transformations
1. Flip horizontal
2. Flip vertical
3. Rotate left
4. Rotate right
Choose a transformation: 3
Enter the name of the output file: rotated-left.ppm
Enjoy your new image!
PPM Image Manipulator
Enter the name of a PPM image file: nonexistant.ppm
Error: Unable to open file nonexistant.ppm.
PPM Image Manipulator
Enter the name of a PPM image file: pixel.h
Error: This is not a PPM image file.
Coding Notes
• Due to a system enforced maximum size for a single data object, an array holding an image must be declared as static. This is a reserved word that precedes a variable declaration. E.g., static pixel_t image[MAX_ROWS][MAX_COLUMNS]; The static reserved word causes the compiler to allocate the space for the declared object in a different place that has no maximum size restrictions.
• Reminder: strings that are used for filenames should have capacity of the predefined constant FILENAME_MAX.
• File names may be read in using scanf since the system will enforce the maximum length.
• Be careful when reading in the magic string. A random textfile may have a first word that is longer than "P3". Recall that fgets can be used to limit the number of characters read.
• Remember to write the header information into the output file first. The magic string goes on a line by itself. The width and the height go on the second line with exactly one space in between. The maximum color value goes on the third line by itself.
• Each pixel must be written on a separate line. The components must have exactly one space in between them.
• Be sure to close the files when you are done using them.
Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
unsigned char r;
unsigned char b;
unsigned char g;
} pixel_t;
pixel_t *image;
#define RGB_COMPONENT_COLOR 255
void flipImage(pixel_t *image, int x, int y);
void grayscale(pixel_t *image, int x, int y);
void rotate(pixel_t *image, int x, int y);
int main(int argc, char *argv[])
{
int width;
int height;
int numPixels;
int i, rgb_comp_color = 255;
char c;
FILE *inFile;
inFile = fopen(argv[2], "r");
//check for comments
c = getc(inFile);
while (c == '#')
{
do
{
c = getc(inFile);
} while (c != ' ');
c = getc(inFile);
}
ungetc(c, inFile);
//read width and height
if (fscanf(inFile, "P6 %d %d", &width, &height) != 2)
{
fprintf(stderr, "Invalid image size. ");
exit(1);
}
//read RGB component
if (fscanf(inFile, "%d ", &rgb_comp_color) != 1)
{
fprintf(stderr, "Invalid RGB component. ");
exit(1);
}
//check RGB depth
if (rgb_comp_color != RGB_COMPONENT_COLOR)
{
fprintf(stderr, "Invalid RGB value. ");
exit(1);
}
numPixels = width*height;
//allocate space
image = malloc (numPixels * sizeof(pixel_t));
//read in pixel data
for (i = 0; i < numPixels; i++)
{
fscanf(inFile, "%c%c%c", &image[i].r, &image[i].g, &image[i].b);
}
//print new header
printf ("P6 ");
printf ("%d %d 255 ", width, height);
switch (*argv[1])
{
case '1':
flipImage(image, width, height);
break;
case '2':
grayscale(image, width, height);
break;
case '3':
//rotate(image, height, width);
break;
default:
printf("Invalid command line argument. User must enter a 1, 2, or 3. ");
break;
}
return 0;
}
void grayscale(pixel_t *image, int x, int y)
{
int i, average = 0;
for (i = 0; i < x*y; i++)
{
average = (image[i].r + image[i].g + image[i].b) / 3;
printf("%c%c%c", average, average, average);
}
}
void flipImage(pixel_t *image, int x, int y)
{
int r, c;
for (c = y-1; c >= 0; c--)
{
for (r = 0; r < x; r++)
{
printf("%c%c%c", image[r].r, image[r].g, image[r].b);
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.