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!