I am struggling to pixelate an image which is made up of RGB values stored in a binary (P6) PPM file. The steps to pixelate the image are as follows:
- Read in the binary data and store it in a 1-dimensional array
 - Iterate through the data stored in this array, in cells of size 'c' (row x columns). This variable 'c' can be changed by the user, but for this program it's currently set to 
int c = 4;meaning it iterates through pixel data in block dimensions of4 x 4 - Now find the average colour value within each of those cells of size 'c'
 - Output each average colour value to a new output PPM file
 
Each binary PPM file begins with a header in the following format, consisting of a 'magic number', followed by the width, height, and finally maximum colour value of 255. Header comments are ignored. The following header example shows a PPM image of format P6 (therefore a binary file), a width of 16, a height of 16, and a max colour value of 255:
P6
16
16
255 
Where I am struggling:
- I am unsure of how to find the average RGB value for each cell, and then output it to the new data stream. I figured out a way to do this when reading the data linearly (i.e. not reading it into an array (or buffer)) by dividing the total colours in that cell by the number of loop iterations, but this proved to be incorrect.
 - Are the nested for loops ordered in a way which changes the orientation of the output image e.g. is it rotating it 180 degrees etc? I am struggling to determine this with reading raw binary data.
 
My attempt:
#define _CRT_SECURE_NO_WARNINGS                 //preprocessor requirement 
#include <stdio.h>                              //library for I/O functions 
#include <stdlib.h>                             //library for general functions 
#define magic_size 10                           //macro for PPM character found within header
typedef struct {
    int t_r, t_g, t_b;                          //Struct to hold  RGB pixel data
} Pixel;
int main()
{
    char magic_number[magic_size];              //variable for PPM format
    int width = 0, height = 0, max_col = 0;     //imagine dimensions
    int c = 4;                                  //mosaic parameter
    /* INPUT FILE HANDLING */
    FILE *inputFile; 
    inputFile = fopen("Sheffield512x512.ppm", "r");
    //input file error handling
    if (inputFile == NULL)
    {
        printf(stderr, "ERROR: file cannot be opened");
        getchar();  //prevent cmd premature closure
        exit(1);    //exit program cleanly
    }
    /* OUTPUT FILE HANDLING */
    FILE *outputFile; 
    outputFile = fopen("mosaic.ppm", "w");
    //output file error handling
    if (outputFile == NULL)
    {
        printf(stderr, "ERROR: cannot write to file");
        getchar();  //prevent cmd premature closure
        exit(1);    //exit program cleanly
    }
    // Scan the header (these variables are used later on)
    fscanf(inputFile, "%s\n%d\n%d\n%d", &magic_number, &width, &height, &max_col);
    // Error handling. Program only supports binary files (i.e. of P6 format) 
    if (magic_number[1] != '6')
    {
        printf("Only Binary images supported!\n");
        getchar();  //prevent cmd premature closure
        return;
    }
    // Raw 1 dimensional store of pixel data
    Pixel *data = malloc(width*height * sizeof(Pixel));
    //2D index to access pixel data
    Pixel **pixels = malloc(height * sizeof(Pixel*));
    // Read the binary file data 
    size_t r = fread(data, width*height, sizeof(unsigned char), inputFile);
    // Build a 1-dimensional index for the binary data 
    for (unsigned int i = 0; i < height; ++i)
    {
        pixels[i] = data + (i * width); 
    }
    // Close the input file 
    fclose(inputFile);
    /* BEGIN PIXELATION PROCESS */
    // Print the OUTPUT file header 
    fprintf(outputFile, "%s\n%d\n%d\n%d", magic_number, width, height, max_col);
    //loop condition variables 
    int cw_x = ceil((double)(width / (float)c));
    int cw_y = ceil((double)(height / (float)c));
    //iterate through 2d array in cells of size c 
    for (int c_x = 0; c_x < cw_x; c_x += 1)
    {
        for (int c_y = 0; c_y < cw_y; c_y += 1)
        {
            //iterate within the cells
            for (int _x = 0; _x < c; _x++)
            {
                int x = c_x * c + _x;
                //bounds checking
                if (x < width)
                {
                    for (int _y = 0; _y < c; _y++)
                    {
                        int y = c_y * c + _y;
                        //bounds checking 
                        if (y < height)
                        {
                            //write data to the output FILE stream 
                            fwrite(data, width*height, sizeof(unsigned char), outputFile);
                        }
                    }
                }
            }
        }
    }
    //close the output file
    fclose(outputFile);
    return 0; 
}