I am writing a program in C which will read in an image in Bitmap format, and adjust some image parameters like colours, making the image greyscale, etc. I have the image loaded in, and have stored the image headers in 2 structs following Microsoft's documentation, here. I'm having trouble dynamically allocating memory for a 2D array which will serve as the new image to be written out. Each index in the matrix will be an RGB struct PX_RGB
:
typedef struct RGB { BYTE rgbPK_BLUE; BYTE rgbPK_GREEN; BYTE rgbPK_RED;} PX_RGB;
I've read a number of threads, most helpfully this one:Calloc a Two-Dimensional Array, and less helpfully this one:I have problems making a function to handle a matrix using calloc. (BYTE is just an alias for a uint8_t). If I naively allocate based solely off of the number of bytes in the input image and the size of the struct
s:
PX_RGB *new_image = calloc(img_information.bi_size_image, sizeof(PX_RGB));
I'm unable to index it as I would like to, like a matrix (i.e. new_image[i][j] = ...
The comments and responses from the first thread seem to indicate placing one of the image dimensions on the left-hand side and allocating this way:
PX_RGB (*new_image)[image_width] = calloc(image_height, image_width * sizeof(PX_RGB));
But the compiler isn't happy about this, as the size of any potential image isn't known at compile time. There's also a different solution, but this just doesn't seem to do anything - neither the check for NULL
neither the code trying to index it seems to do anything:
PX_RGB **new_image;new_image = calloc(image_height, image_width * sizeof(new_image));if (new_image == NULL) { printf("\nError: Could not allocate image memory.\n"); return -1; }for (int i = 0; i < image_height; i++){ for (int j = 0; j < image_width; j++) { new_image[i][j].rgbPK_BLUE = j; printf("\nIndex [%d][%d] = %d", i, j, new_image[i][j].rgbPK_BLUE); }}
I had seen this used as an answer in the first thread, but there the number of columns needed was known and hard-coded in ([3]).I came across this formula for getting the correct row offset here, and with this test code seems to work fine, I think:
PX_RGB *new_image = calloc(image_height, image_width * sizeof(new_image));int offset = 0;for (int i = 0; i < image_height; i++){ for (int j = 0; j < image_width; j++) { offset = (j * image_width) + i; new_image[offset].rgbPK_BLUE = j; printf("\nIndex [%d][%d] = %d", i, j, new_image[offset].rgbPK_BLUE); }}
So, is there no way to index dynamically allocated memory the way I want to? I would ideally like to pass my new image to the manipulation functions like this:
void grayscale(int image_height, int image_width, PX_RGB new_image[image_height][image_width]){ return;}
because I have seen other code doing this and I'm stumped why I can't get my version working, and what I'm doing wrong. I should say I got the idea for this project from an open lecture series on computer science by Harvard on edX, where they seemed to have implemented this logic in the way that I want to. Help would be hugely appreciated, cheers!