summaryrefslogtreecommitdiff
path: root/unvignette.c
diff options
context:
space:
mode:
Diffstat (limited to 'unvignette.c')
-rw-r--r--unvignette.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/unvignette.c b/unvignette.c
new file mode 100644
index 0000000..36e30e7
--- /dev/null
+++ b/unvignette.c
@@ -0,0 +1,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;
+}