Rain
Rain

Reputation: 43

What is causing these array values to not match?

I have a function that takes the loaded (raw) values from a PNG file and stores them in a new array so that each colour channel is contiguous--i.e. the first third of the array should just be the red values, then the green, then the blue.

For the moment, I have it output every value just stored:

*array_length = (NUMBER_PIXELS * 3); //record array size--one value per pixel per colour channel
unsigned char *loaded_image = malloc(sizeof(char) * *array_length); //allocate array memory
if (loaded_image != NULL) 
{
    for (int i = 0; i < NUMBER_PIXELS; i+=3)
    {
        *(loaded_image + i) = *(load_output + i); //red colour channel. 
        printf("%d ", *(load_output + i));
        *(loaded_image + NUMBER_PIXELS + i) = *(load_output + 1 + i); //green colour channel
        printf("%d ", *(load_output + 1 + i));
        *(loaded_image + (2 * NUMBER_PIXELS) + i) = *(load_output + 2 + i); //blue colour channel
        printf("%d \n", *(load_output + 2 + i));
    }
    free(load_output);
    return loaded_image; //return the array

Then, in another method, I print out the entire contents of the array in order:

int array_length;
unsigned char *image = load_image("TestImage.png", &array_length);
if (image != NULL) {
    for (int i = 0; i < array_length; i++)
    {
        printf("%d \n", *(image + i));
    }
    free(image);
}

The output doesn't match the input: for no reason that I can apparently tell, the array has 205 appearing a lot of the time (which makes no sense for a test image entirely red) and out of order. As far as I can see, there are no type mismatches or regions of overlap, yet the printed output looks like this.

EDIT: Compilable version that produces an array with the same output as the image loading and same print output:

#include <stdio.h>
#include <stdlib.h>

unsigned char
*load_image(char* file_location, int *array_length)
{
    int num_pixels = 64 * 64;
    *array_length = (num_pixels * 3); //record array size--one value per pixel per colour channel
    unsigned char *load_output = malloc(sizeof(char) * *array_length);
    unsigned char *loaded_image = malloc(sizeof(char) * *array_length); //allocate array memory
    for (int i = 0; i < *array_length; i++) {
        if (i % 3 == 0)
            *(load_output + i) = 255;
        else
            *(load_output + i) = 0;
    }
    if (loaded_image != NULL) 
    {
        for (int i = 0; i < num_pixels; i+=3)
        {
            *(loaded_image + i) = *(load_output + i); //red colour channel. 
            printf("%d ", *(load_output + i));
            *(loaded_image + num_pixels + i) = *(load_output + 1 + i); //green colour channel
            printf("%d ", *(load_output + 1 + i));
            *(loaded_image + (2 * num_pixels) + i) = *(load_output + 2 + i); //blue colour channel
            printf("%d \n", *(load_output + 2 + i));
        }
        free(load_output);
        return loaded_image; //return the array
    }
    else 
    {
        return NULL;
    }
}

int main(void)
{
    int array_length;
    unsigned char *image = load_image("TestImage.png", &array_length);
    if (image != NULL) {
        for (int i = 0; i < array_length; i++)
        {
            printf("%d \n", *(image + i));
        }
        free(image);
    }
}

Upvotes: 1

Views: 62

Answers (1)

ad absurdum
ad absurdum

Reputation: 21323

The loop indices are off in the loop that converts load_output to loaded_image. You need to increment i by one on every interation, and increment load_output by 3*i:

for (int i = 0; i < num_pixels; i++)
        {
            *(loaded_image + i) = *(load_output + 3*i); //red colour channel. 
            printf("%d ", *(load_output + i));
            *(loaded_image + num_pixels + i) = *(load_output + 1 + 3*i); //green colour channel
            printf("%d ", *(load_output + 1 + i));
            *(loaded_image + (2 * num_pixels) + i) = *(load_output + 2 + 3*i); //blue colour channel
            printf("%d \n", *(load_output + 2 + i));
        }

Upvotes: 1

Related Questions