Write a C program to (read, write, copy, grow, shrink) a ppm file... Manipulatin
ID: 3693924 • Letter: W
Question
Write a C program to (read, write, copy, grow, shrink) a ppm file... Manipulating the ppm file basically.
typedef struct ppm {
int rows;
int cols;
int colors;
Pixel **pixels;
} ppmPic;
typedef struct pixel {
int red;
int green;
int blue;
} Pixel;
It will be using command line arguments as well so it should read from the command line argument
Example:
./a.out copy beach.ppm newBeach.ppm
./a.out grow florida.ppm UF.ppm
./a.out shrink mountain.ppm m2.ppm
The very first line is always P3
Example format:
P3
4 6 255
255 0 0
Any help with the (read, write, copy, grow, shrink) functions would help tremendously!
Thank You
http://troll.cs.ua.edu/cs100/projects/project5.pdf
Explanation / Answer
main.c
#include <stdio.h>
#include "scanner.h"
#include <stdlib.h>
#include "ppm.h"
int main (int argc, char **argv){
ppmPic *head = NULL;
if(strcmp(argv[1], "copy")==0){
copy(argv[2], argv[3]);
}
if(strcmp(argv[1], "grow")==0){
head = read(argv[2]);
grow(argv[2], argv[3], head);
}
if(strcmp(argv[1], "shrink")==0){
head = read(argv[2]);
shrink(argv[2], argv[3], head);
}
return 0;
}
ppm.c
#include "ppm.h"
#include "scanner.h"
ppmPic *read(char *name){
ppmPic *ptr = malloc(sizeof(ppmPic));
FILE *fp = fopen(name, "r");
readToken(fp);
ptr->cols = readInt(fp);
ptr->rows = readInt(fp);
ptr->colors = readInt(fp);
int i, j;
int a;
Pixel **pix;
pix = malloc(sizeof(Pixel *) * ptr->rows);
for (a=0; a<ptr->rows; a++)
pix[a] = malloc(sizeof(Pixel) * ptr->cols);
for (i = 0; i<ptr->rows; i++){
for (j=0; j<ptr->cols; j++){
pix[i][j].red = readInt(fp);
pix[i][j].blue = readInt(fp);
pix[i][j].green = readInt(fp);
}
}
ptr->pixels = pix;
fclose(fp);
return ptr;
}
void write(char *name, char *name2, ppmPic *head){
FILE *fp = fopen(name2, "w");
ppmPic *ptr = head;
fprintf(fp, "P3 %d %d %d ", ptr->cols, ptr->rows, ptr->colors);
Pixel **pix;
pix = ptr->pixels;
int i, j;
for (i = 0; i<ptr->rows; i++){
for (j=0; j<ptr->cols; j++){
fprintf(fp, "%d %d %d ", pix[i][j].red, pix[i][j].blue, pix[i][j].green);
}
}
fclose (fp);
return;
}
void copy(char *name, char *name2){
ppmPic *head = read(name);
write(name, name2, head);
return;
}
void grow(char *name, char *name2, ppmPic *head){
int col = head->cols;
int row = head->rows;
FILE *fp = fopen(name2, "w");
ppmPic *ptr = head;
ptr->cols = col*2;
ptr->rows = row*2;
fprintf(fp, "P3 %d %d %d ", ptr->cols, ptr->rows, ptr->colors);
Pixel **pix;
pix = ptr->pixels;
printf("hello ");
int i, j;
for (i = 0; i<row; i++){
for (j=0; j<col; j++){
fprintf(fp, "%d %d %d ", pix[i][j].red, pix[i][j].blue, pix[i][j].green);
fprintf(fp, "%d %d %d ", pix[i][j].red, pix[i][j].blue, pix[i][j].green);
}
j = 0;
for (j=0; j<col; j++){
fprintf(fp, "%d %d %d ", pix[i][j].red, pix[i][j].blue, pix[i][j].green);
fprintf(fp, "%d %d %d ", pix[i][j].red, pix[i][j].blue, pix[i][j].green);
}
}
fclose(fp);
return;
}
void shrink(char *name, char *name2, ppmPic *head){
printf("shrink");
return;
}
ppm.h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct pixel {
int red; // red value
int green; // green value
int blue; // blue value
} Pixel;
typedef struct ppm {
int rows; // number of rows
int cols; // number of columns
int colors; // number of colors
Pixel **pixels; // actual pixel data
} ppmPic;
ppmPic *read(char *);
void write(char *, char *, ppmPic *);
void copy(char *, char *);
void grow(char *, char *, ppmPic *head);
void shrink();
scanner.c
#include <stdio.h>
#include <stdlib.h> /* for exit, malloc, realloc */
#include <ctype.h> /* for isspace */
#include <string.h> /* for strdup */
#include "scanner.h"
/* * readInt(FILE *)
* - wrapper for fscanf(fp,"%d")
* - returns 0 if end of file, but feof will subsequently return true
* - usage example: int x = readInt(stdin);
* readReal(FILE *)
* - wrapper for fscanf(fp,"%lf")
* - returns a double
* - returns 0.0 if read fails due to end of file,
* but feof will subsequently return true
* - usage example: double x = readReal(stdin);
* readChar(FILE *)
* - wrapper for fscanf(fp," %c")
* - returns a non-whitespace character
* - returns 0 if end of file; feof will subsequently return true
* - usage example: char x = readChar(stdin);
* readRawChar(FILE *fp)
* - wrapper for fscanf(fp,"%c")
* - returns a character, whether whitespace or non-whitespace
* - returns 0 if end of file; feof will subsequently return true
* - usage example: char x = readRawChar(stdin);
* readToken(FILE *fp)
* - safe version of fscanf(fp,"%s")
* - returns a malloc'd string
* the caller should free the returned string
* - returns 0 if end of file; feof will subsequently return true
* - usage example: char *x = readToken(stdin);
* readString(FILE *fp)
* - reads in a double quoted string
* - returns a malloc'd string; the quotation marks are not included
* the caller should free the returned string
* - returns 0 if end of file; feof will subsequently return true
* - usage example: char *x = readString(stdin);
* readLine(FILE *fp)
* - reads in a line or remainder of a line
* - returns a malloc'd string; the newline is not included
* the caller should free the returned string
* - returns 0 if end of file; feof will subsequently return true
* - usage example: char *x = readLine(stdin);
* allocate(size_t size)
* - wrapper for malloc that will generate an out of memory error
* - usage example: int *x = (int *) allocate(sizeof(int) * count);
* reallocate(void *items,size_t size)
* - wrapper for realloc that will generate an out of memory error
* - usage example: x = (int *) reallocate(x,sizeof(int) * count);
*/
static void skipWhiteSpace(FILE *);
static char convertEscapedChar(int);
static void *allocateMsg(size_t,char *);
static void *reallocateMsg(void *,size_t,char *);
/********** public functions **********************/
int
readInt(FILE *fp)
{
int x,result;
result = fscanf(fp,"%d",&x);
if (result == EOF)
{
return 0;
}
if (result == 0)
{
fprintf(stderr,"SCAN ERROR: attempt to read an integer failed ");
fprintf(stderr,"offending character was <%c> ",fgetc(fp));
exit(1);
}
return x;
}
double
readReal(FILE *fp)
{
int result;
double x;
result = fscanf(fp," %lf",&x);
if (result == EOF)
{
return 0.0;
}
if (result == 0)
{
fprintf(stderr,"SCAN ERROR: attempt to read a real number failed ");
fprintf(stderr,"offending character was <%c> ",fgetc(fp));
exit(2);
}
return x;
}
char
readChar(FILE *fp)
{
int result;
char x;
result = fscanf(fp," %c",&x);
if (result == EOF)
{
return -1;
}
if (result == 0)
{
fprintf(stderr,"SCAN ERROR: attempt to read a non-whitespace character failed ");
fprintf(stderr,"offending character was <%c> ",fgetc(fp));
exit(2);
}
return x;
}
char
readRawChar(FILE *fp)
{
int result;
char x;
result = fscanf(fp,"%c",&x);
if (result == EOF)
{
return -1;
}
if (result == 0)
{
fprintf(stderr,"SCAN ERROR: attempt to read a raw character failed ");
fprintf(stderr,"offending character was <%c> ",fgetc(fp));
exit(2);
}
return x;
}
char *
readString(FILE *fp)
{
int ch,index;
char *buffer;
int size = 512;
/* advance to the double quote */
skipWhiteSpace(fp);
ch = fgetc(fp);
if (ch == EOF) return 0;
/* allocate the buffer */
buffer = allocateMsg(size,"readString");
if (ch != '"')
{
fprintf(stderr,"SCAN ERROR: attempt to read a string failed ");
fprintf(stderr,"first character was <%c> ",ch);
exit(4);
}
/* toss the double quote, skip to the next character */
ch = fgetc(fp);
/* initialize the buffer index */
index = 0;
/* collect characters until the closing double quote */
while (ch != '"')
{
if (ch == EOF)
{
fprintf(stderr,"SCAN ERROR: attempt to read a string failed ");
fprintf(stderr,"no closing double quote ");
exit(6);
}
if (index > size - 2)
{
++size;
buffer = reallocateMsg(buffer,size,"readString");
}
if (ch == '\')
{
ch = fgetc(fp);
if (ch == EOF)
{
fprintf(stderr,"SCAN ERROR: attempt to read a string failed ");
fprintf(stderr,"escaped character missing ");
exit(6);
}
buffer[index] = convertEscapedChar(ch);
}
else
buffer[index] = ch;
++index;
ch = fgetc(fp);
}
buffer[index] = '';
return buffer;
}
char *
readToken(FILE *fp)
{
int ch,index;
char *buffer;
int size = 80;
skipWhiteSpace(fp);
ch = fgetc(fp);
if (ch == EOF) return 0;
buffer = allocateMsg(size,"readToken");
index = 0;
while (!isspace(ch))
{
if (ch == EOF) break;
if (index > size - 2)
{
++size;
buffer = reallocateMsg(buffer,size,"readToken");
}
buffer[index] = ch;
++index;
ch = fgetc(fp);
}
/* push back the character that got us out of this loop */
ungetc(ch,fp);
if (index > 0) //there is something in the buffer
clearerr(fp); //so force the read to be good
buffer[index] = '';
return buffer;
}
char *
readLine(FILE *fp)
{
int ch,index;
char *buffer;
int size = 512;
ch = fgetc(fp);
if (ch == EOF) return 0;
buffer = allocateMsg(size,"readLine");
index = 0;
while (ch != ' ')
{
if (ch == EOF) break;
if (index > size - 2)
{
++size;
buffer = reallocateMsg(buffer,size,"readLine");
}
buffer[index] = ch;
++index;
ch = fgetc(fp);
}
if (index > 0) //there is something in the buffer
clearerr(fp); //so force the read to be good
buffer[index] = '';
return buffer;
}
/********** private functions **********************/
static void
skipWhiteSpace(FILE *fp)
{
int ch;
/* read chars until a non-whitespace character is encountered */
while ((ch = fgetc(fp)) != EOF && isspace(ch))
continue;
/* a non-space character got us out of the loop, so push it back */
ungetc(ch,fp);
}
static char
convertEscapedChar(int ch)
{
switch (ch)
{
case 'n': return ' ';
case 't': return ' ';
case '"': return '"';
case '\': return '\';
}
return ch;
}
void *
allocate(size_t size)
{
char *s;
s = malloc(size);
if (s == 0)
{
fprintf(stderr,"could not allocate string, out of memory ");
exit(3);
}
return s;
}
void *
reallocate(void *s,size_t size)
{
char *t;
t = realloc(s,size);
if (t == 0)
{
fprintf(stderr,"could not reallocate string, out of memory ");
exit(3);
}
return t;
}
void *
allocateMsg(size_t size,char *where)
{
char *s;
s = malloc(size);
if (s == 0)
{
fprintf(stderr,"%s: could not allocate string, out of memory ",
where);
exit(3);
}
return s;
}
static void *
reallocateMsg(void *s,size_t size,char *where)
{
char *t;
t = realloc(s,size);
if (t == 0)
{
fprintf(stderr,"%s: could not reallocate string, out of memory ",
where);
exit(3);
}
return t;
}
scanner.h
#ifndef SCANNER_H
#define SCANNER_H
extern int readInt(FILE *);
extern double readReal(FILE *);
extern char readChar(FILE *);
extern char readRawChar(FILE *);
extern char *readString(FILE *);
extern char *readToken(FILE *);
extern char *readLine(FILE *);
extern void *allocate(size_t);
extern void *reallocate(void *,size_t);
#endif
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.