2

I'm trying to read an image into a 2D array and then make modifications to its RGB values and create a resize function next. The dimensions of the image aren't known until the image is loaded so it looks something like this.

I've tried passing in "pixels" into the unsigned char ** and pixels[0][0] to unsigned char* and quite a few other ways I can't remember. I've searched around the web for different methods but none of them seem to work. I've seen that if you define the size of one of the arrays like pixels[][40] it works, but I don't know the size until after the image is loaded.

void invertImg(unsigned char **img, int height, int width)
{
    int h, w;
    for (h = 0; h < height; h++){
        for (w = 0; w < width * 3; w += 3){
            //Blue
            img[h][w] = ~img[h][w];
            //Green
            img[h][w + 1] = ~img[h][w + 1];
            //Red
            img[h][w + 2] = ~img[h][w + 2];
        }
    }
}


    // Get Image name and desired dimensions

    char header[54];
    unsigned char pixels[height][width * 3];

    FILE *in = fopen(img, "rb");
    FILE *out = fopen("out.bmp", "wb");

    fread(header, 1, 54, in);
    fread(pixels, 1, height * width * 3, in);


//function that the 2d array needs to be passed into
invertImg(pixels, height, width);


    fwrite(header, sizeof(char), HEADER_SIZE, out);
    fwrite(pixels, sizeof(char), height * width * 3, out);

    fclose(in);
    fclose(out);

How can I get this unsigned char array into the function to be able to modify its values?

8
  • Good duplicate anyone? Similar questions are asked daily. Commented Feb 7, 2019 at 17:40
  • Because C support variable-length arrays, you can use that also for function arguments. But then the dimensions (sizes) needs to be know first, for example by passing them as arguments before the array. Commented Feb 7, 2019 at 17:42
  • You could cast the argument to type char** and keep your function the way it is. Or, you could dynamically allocate and would have char** nonetheless. Commented Feb 7, 2019 at 17:45
  • The simplest would be to read the file twice - once to get the size and once to read it into your array. Anything else will be much more complex, and therefore be more prone to bugs, and I think would count as premature optimisation unless you have a very strong reason not to. Commented Feb 7, 2019 at 17:48
  • @nm_tp An array of arrays is not the same as a pointer to a pointer. Commented Feb 7, 2019 at 17:48

2 Answers 2

3

You can pass a multidimensional array with sizes based on other parameters:

void invertImg(int height, int width, unsigned char img[height][width])
{
    ...

A declaration for this function without parameter names would look like this:

void invertImg(int, int, unsigned char img[*][*]);

Then you can call the function like this:

invertImg(height, width, pixels);
Sign up to request clarification or add additional context in comments.

Comments

0
void invertImg(unsigned char *img, int height, int width)
{
    int h, w;
    for (h = 0; h < height; h++){
        for (w = 0; w < width; w++){
            for (color = 0; color < 3, ++color) {
                img[ 3*width*h + 3*w + color] = ~img[ 3*width*h + 3*w + color]
            }
        }
    }
}

2 Comments

To avoid code duplication I would xor with 0xFF instead. BTW, you are missing semicolon.
Note that we are using just a char pointer, not a pointer to an array. Also, this is an example of how zero based indexing is practical. One based counting would be messier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.