Kablooie99
Kablooie99

Reputation: 1

How can I store a P6 PPM File into a PPM struct in C?

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

Answers (0)

Related Questions