ANSI C: How can I abstract over structure fields?

I have an image rendered as a 2D RGB pixel array.

typedef struct {
    char R;
    char G;
    char B;
} RGB;

      

and a function that calculates a new color for each pixel for this image:

RGB new_color(RGB image[][], int r, int c){
    RGB color;
    color.R = image[r][c].R + image[r+1][c].R + image[r-1][c].R + image[r][c+1].R + image[r][c-1].R;
    color.G = image[r][c].G + image[r+1][c].G + image[r-1][c].G + image[r][c+1].G + image[r][c-1].G;
    color.B = image[r][c].B + image[r+1][c].B + image[r-1][c].B + image[r][c+1].B + image[r][c-1].B;
    return color;
}

      

Is it possible to remove duplicate code in the body of new_color? In other words, abstractly over the field names of the RGB data structure?

+3


source to share


1 answer


Let's ignore now, which is RGB image[][]

not legal in C89.

You can unlock access functions.

char *get_RGB_R(RGB* rgb) { return &rgb->R; }
char *get_RGB_G(RGB* rgb) { return &rgb->G; }
char *get_RGB_B(RGB* rgb) { return &rgb->B; }

      

And then write a helper function that uses them.



void set_color_channel_from_adjacent(
    char *(*accessor)(RGB*), RGB* result, RGB image[][], int r, int c)
{
    *accessor(result) = *accessor(&image[r][c]) +
                        *accessor(&image[r+1][c]) + 
                        *accessor(&image[r-1][c]) + 
                        *accessor(&image[r][c+1]) + 
                        *accessor(&image[r][c-1]);
}

      

And then call the helper function

RGB new_color(RGB image[][], int r, int c)
{
    RGB color;
    set_color_channel_from_adjacent(get_RGB_R, &color, image, r, c);
    set_color_channel_from_adjacent(get_RGB_G, &color, image, r, c);
    set_color_channel_from_adjacent(get_RGB_B, &color, image, r, c);
    return color;
}

      

Modern compilers build short functions and generate equivalent code to the original.

+5


source







All Articles