I would like to implement a configurable filter for an image processing application.
For this I have a square kernel typically this one for the first pass of a Sobel filter
-1 0 1
-2 0 2
-1 0 1
I can declare my kernel as a fixed array:
#define KERNEL_SIZE 3
int8_t kernel[][KERNEL_SIZE] = {{0,0,0},{0,0,0},{0,0,0}};
With this solution it is easy to pass the kernel to the filtering function:
void filter(char* pixels, kernel[][KERNEL_SIZE]);
However passing the kernel by value is not very wise, especially if the kernel is big and my goal is to allow variable kernel size.
The actual solution I've found is to write this:
size_t kernel_size = 3;
int8_t *kernel = malloc(sizeof(int8_t)*kernel_size*kernel_size);
void filter(char* pixels, char *kernel, size_t kernel_size);
Unfortunately I am not happy with this because I cannot easily access the kernel's rows and columns like before.
I feel this is less readable:
for(x = 0; x < kernel_size; x++)
for(y = 0; y < kernel_size; y++)
int8_t k = kernel[x + y * kernel_size];
than this:
for(x = 0; x < kernel_size; x++)
for(y = 0; y < kernel_size; y++)
int8_t k = kernel[x][y];
Also the prototype of filter does not give any clue to what the kernel
is exactly. It is better if I can directly express that a kernel is a square bi-dimensional array. Unfortunately this statement below is not valid:
void filter(char* pixels, char kernel[][size_t kernel_size]);
The alternative is to use an array of pointers:
void filter(char* pixels, char *kernel[], size_t kernel_size);
But I doubt this solution will be more efficient that the previous one because in memory I will have my data + a pointer to each row which is not very good.
So, my question is:
How to properly pass a bi-dimensional array by reference to a function when the size of the array can be variable?
NOTE: Some might advise to use tools like ImageMagick but, here I am just playing with C and this example is pure didactic. I would like to understand more how to pass complex arrays in C
NOTE-bis: Actually the full solution to this problem would be the case of a n-dimensional array.