Reputation: 1
I need to write a program that can store both a plain PPM file (P3) as well as a normal PPM file (P6). I am anyways unclear as to how a P6 PPM file is written, and so cannot figure out how to load it into a struct. I have been able to load a P3 PPM file without any issue. How can I edit the code to allow it to store P6 PPM files into the same struct? Or would I need to make a new struct to accommodate the P6 format?
I have the following code already written:
/*------------ Pixel struct ------------*/
struct Pixel {
int red;
int green;
int blue;
};
typedef struct Pixel PIXEL;
/*------------ LinkedList Node struct ------------*/
struct Node {
char *value;
struct Node *next;
};
typedef struct Node NODE;
/*------------ PPM struct ------------*/
struct PPM {
char *Format;
NODE *comments;
int commentCounter;
int width, height;
int max;
PIXEL **pixelArray;
};
typedef struct PPM PPM;
/*------------ Function Prototypes ------------*/
PPM* getPPM(FILE *f);
void showPPM(const PPM *img);
PPM* readPPM(const char *filename);
//HELPER FUNCTIONS
char* readLine(FILE *f);
void getComments(FILE *f, PPM *img);
/*------------ getPPM Function ------------*/
PPM* getPPM(FILE * f)
{
if (f == NULL) {
fprintf(stderr,"ERROR! Could not read file");
return NULL;
} //Checks if image was able to be read
PPM *allocPPM = malloc(sizeof(PPM)); //Allocate memory for PPM struct
//FORMAT
allocPPM->Format = malloc(3 * sizeof(char));
allocPPM->Format = readLine(f);
//COMMENTS
allocPPM->commentCounter = 0;
getComments(f, allocPPM);
//SIZES
fscanf(f, "%d", &allocPPM->width);
fscanf(f, "%d", &allocPPM->height);
fscanf(f, "%d", &allocPPM->max);
//PIXELS
allocPPM->pixelArray = calloc(allocPPM->height, sizeof(PIXEL)); //Allocates memory for rows
for(int i=0 ; i<allocPPM->height ; i++)
{
allocPPM->pixelArray[i] = calloc(allocPPM->width, sizeof(PIXEL)); //Allocates memory for columns
for(int j=0 ; j<allocPPM->width ; j++)
{
fscanf(f, "%d", &(allocPPM->pixelArray[i][j].red));
fscanf(f, "%d", &(allocPPM->pixelArray[i][j].green));
fscanf(f, "%d", &(allocPPM->pixelArray[i][j].blue));
}
}
return allocPPM;
}
/*------------ getPPM Function ------------*/
/*------------ helper Functions ------------*/
char* readLine(FILE *f)
{
char dummy[BUFFER]; //Dummy string used so line is not over-allocated
char *line;
char chr;
int count = 0;
chr = getc(f);
if (chr == EOF) { return NULL; } //Empty file checker
//Populate dummy char by char
while (chr!='\n' && count < BUFFER-1)
{
dummy[count] = chr;
count++;
chr = getc(f);
}
dummy[count] = '\0';
//Populating line from dummy
line = calloc((count+1), sizeof(char));
for(int i=0 ; i<count ; i++)
{
line[i] = dummy[i];
}
line[count] = '\0';
return line;
free(dummy); //Free dummy to get rid of overly-allocated string
}
void getComments(FILE *f, PPM *img) //Gets comments from file f and inputs them into PPM struct using LinkedLists
{
char chr = getc(f);
while(chr == '#')
{
//Gets comment with #
ungetc(chr, f);
char *line = readLine(f);
//ADD COMMENT TO LINKED LIST
if(img->commentCounter == 0) { //Head Node
img->comments = malloc(sizeof(NODE));
img->comments->value = line;
img->commentCounter = 1;
} else { //Next Node
NODE *currentNode = img->comments;
for(int count=1 ; count<img->commentCounter ; count++)
{
currentNode = currentNode->next;
}
currentNode->next = malloc(sizeof(NODE));
currentNode->next->value = line;
img->commentCounter = img->commentCounter + 1;
}
//Move to next line
chr = getc(f);
}
//Return to starting position
ungetc(chr, f);
}
I've added the helper functions as well in case it helps to better understand the other functions.
Upvotes: 0
Views: 94