summaryrefslogtreecommitdiff
path: root/unvignette.c
blob: 36e30e77bcb7dca68881ee31f5025e8b3ce1ca06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cairo.h>

#define CLAMP(x, l, h) (((x) > (h)) ? (h) : (((x) < (l)) ? (l) : (x)))

static inline double
cos4(double x)
{
	return CLAMP(pow(cos(x), 4.0), 0.001, 1.0);
}

int
main(int argc, char *argv[])
{
	cairo_surface_t *s;
	unsigned char *row, *p;
	int x, y, i, width, height, stride;

	if (argc < 2)
		exit(EXIT_FAILURE);

	s = cairo_image_surface_create_from_png(argv[1]);
	if (!s || cairo_surface_status(s) != CAIRO_STATUS_SUCCESS)
		exit(EXIT_FAILURE);

	row    = cairo_image_surface_get_data(s);
	width  = cairo_image_surface_get_width(s);
	height = cairo_image_surface_get_height(s);
	stride = cairo_image_surface_get_stride(s);

	for (y = 0; y < height; ++y, row += stride) {
		for (x = 0, p = row; x < width; ++x, p += 4) {
			double c = 1.0 / cos4(1.2 * (x - width / 2) / width);
			for (i = 0; i < 3; ++i)
				p[i] = CLAMP(c * p[i], 0, 255);
		}
	}

	cairo_surface_write_to_png(s, argc > 2 ? argv[2] : "unvignetted.png");
	cairo_surface_destroy(s);

	return 0;
}