#include #include #include #include #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; }