c – Super-sampling anti-aliasing for a curve via libpng

I tried to smoothen a line via the super-sampling anti-aliasing technique by adding transparency to neighboring pixels. Here is the code in C

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <png.h>

#define WIDTH 512
#define HEIGHT 512

int main()
{
    // Image buffer
    unsigned char image[HEIGHT][WIDTH][4];

    for (int i = 0; i < HEIGHT; i++)
    {
        for (int j = 0; j < WIDTH; j++)
        {
            image[i][j][0] = 255;
            image[i][j][1] = 255;
            image[i][j][2] = 255;
            image[i][j][3] = 0;
        }
    }

    // A sample curve
    for (double x = -M_PI; x <= M_PI; x += M_PI / WIDTH)
    {
        int y = (int)(HEIGHT / 2 - sin(x) * cos(x) * HEIGHT / 2);
        int i = (int)(x * WIDTH / (2 * M_PI) + WIDTH / 2);

        // The anti-aliasing part
        int sample = 2; // how far we are sampling
        double max_distance = sqrt(sample * sample + sample * sample);
        for (int ii = -sample; ii <= sample; ii++)
        {
            for (int jj = -sample; jj <= sample; jj++)
            {
                int iii = i + ii;
                int jjj = y + jj;
                if (iii >= 0 && iii < WIDTH && jjj >= 0 && jjj < HEIGHT)
                {
                    // Here is my question
                    int alpha = 255 - (int)(100.0 * sqrt(ii * ii + jj * jj) / max_distance);
                    image[jjj][iii][0] = 0;
                    image[jjj][iii][1] = 0;
                    image[jjj][iii][2] = 0;
                    image[jjj][iii][3] = alpha > image[jjj][iii][3] ? alpha : image[jjj][iii][3];
                }
            }
        }
    }

    FILE *fp = fopen("curve.png", "wb");
    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_set_IHDR(png, info, WIDTH, HEIGHT, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    png_write_info(png, info);
    for (int i = 0; i < HEIGHT; i++)
    {
        png_write_row(png, (png_bytep)image[i]);
    }
    png_write_end(png, NULL);
    fclose(fp);

    return 0;
}

Although it does some smoothing, but the result is far from the available programs. Where did I do wrong?

I tried to calculate the transparency based on the distance of each neighboring pixel from the center of the line:

int alpha = 255 - (int)(100.0 * sqrt(ii * ii + jj * jj) / max_distance);

I used the factor of 100 instead of 255 since we do not need to go deep into full transparency.

UPDATE: Right after posting the question, I realized that the loop is re-writing on each pixel. Then, I used a transparent background to avoid this problem.

Read more here: Source link