aboutsummaryrefslogtreecommitdiff
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/src/image.c b/src/image.c
new file mode 100644
index 0000000..4295ab1
--- /dev/null
+++ b/src/image.c
@@ -0,0 +1,222 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <cairo/cairo.h>
+#include <pango/pangocairo.h>
+#include <wand/MagickWand.h>
+#include "draw.h"
+
+
+// Used for MagickWand
+#define ThrowWandException(wand) \
+{ \
+ char \
+ *description; \
+ \
+ ExceptionType \
+ severity; \
+ \
+ description=MagickGetException(wand,&severity); \
+ (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
+ description=(char *) MagickRelinquishMemory(description); \
+ exit(-1); \
+}
+
+
+
+// Draw an image at a specific point
+int draw_image(cairo_t *c, char *path, double x, double y) {
+ cairo_surface_t *image;
+
+ // Checks if the file exists. If it doesn't, warn the user that it was not found.
+ // A file not existing will not terminate the program, but simply not render the image.
+ FILE *file;
+ if((file = fopen(path, "r")) != NULL)
+ {
+ // file exists
+ fclose(file);
+ }
+ else
+ {
+ printf("Warning: image \'%s\' does not exist.\n", path);
+ return 1;
+ }
+
+ image = cairo_image_surface_create_from_png(path);
+ cairo_set_source_surface(c, image, x, y);
+ cairo_paint(c);
+
+ cairo_surface_destroy (image);
+ return 0;
+}
+
+
+
+
+
+
+unsigned long get_image_width(char *path) {
+ MagickBooleanType status;
+ MagickWand *wand;
+
+ MagickWandGenesis();
+ wand = NewMagickWand();
+ status = MagickReadImage(wand, path);
+
+ if (status == MagickFalse) {
+ ThrowWandException(wand);
+ }
+
+ unsigned long width = MagickGetImageWidth(wand);
+
+ wand = DestroyMagickWand(wand);
+ MagickWandTerminus();
+ return width;
+}
+
+
+
+unsigned long get_image_height(char *path) {
+ MagickBooleanType status;
+ MagickWand *wand;
+
+ MagickWandGenesis();
+ wand = NewMagickWand();
+ status = MagickReadImage(wand, path);
+
+ if (status == MagickFalse) {
+ ThrowWandException(wand);
+ }
+
+ unsigned long height = MagickGetImageHeight(wand);
+
+ wand = DestroyMagickWand(wand);
+ MagickWandTerminus();
+ return height;
+}
+
+
+
+
+
+// Resize an image to a specific width and height.
+// Optionally create a new file to preserve the source image.
+int resize_image(char *path, double width, double height, bool create_new) {
+ MagickBooleanType status;
+ MagickWand *wand;
+
+ MagickWandGenesis();
+ wand = NewMagickWand();
+ status = MagickReadImage(wand, path);
+
+ if (status == MagickFalse) {
+ ThrowWandException(wand);
+ }
+
+ MagickResetIterator(wand);
+
+ MagickResizeImage(wand, width, height, LanczosFilter, 1.0);
+
+ if (create_new == true) {
+ char new_path[30];
+ snprintf(new_path, sizeof(new_path), "%s.tmp", path);
+ status = MagickWriteImages(wand, new_path, MagickTrue);
+ } else {
+ status = MagickWriteImages(wand, path, MagickTrue);
+ }
+
+ if (status == MagickFalse) {
+ ThrowWandException(wand);
+ }
+ wand = DestroyMagickWand(wand);
+ MagickWandTerminus();
+ return 0;
+}
+
+
+// Create a cropped version of an image to a certain dimensions and position.
+// Optionally create a new file to preserve the source image.
+int crop_image(char *path, double width, double height, double x, double y, bool create_new) {
+ MagickBooleanType status;
+ MagickWand *wand;
+
+ MagickWandGenesis();
+ wand = NewMagickWand();
+ status = MagickReadImage(wand, path);
+
+ if (status == MagickFalse) {
+ ThrowWandException(wand);
+ }
+
+ MagickResetIterator(wand);
+
+ MagickCropImage(wand, width, height, x, y);
+
+ if (create_new == true) {
+ char new_path[30];
+ snprintf(new_path, sizeof(new_path), "%s.tmp", path);
+ status = MagickWriteImages(wand, new_path, MagickTrue);
+ } else {
+ status = MagickWriteImages(wand, path, MagickTrue);
+ }
+
+ if (status == MagickFalse) {
+ ThrowWandException(wand);
+ }
+ wand = DestroyMagickWand(wand);
+ MagickWandTerminus();
+ return 0;
+}
+
+
+int prepare_month_art(char *path, struct dimensions *d) {
+ if (!d->header_width || !d->header_height) {
+ printf("Error: header_width and header_height unknown.\n");
+ return 1;
+ }
+
+ double desired_ratio = d->header_width / d->header_height;
+
+ unsigned long width = get_image_width(path);
+ unsigned long height = get_image_height(path);
+ //double original_ratio = width / height;
+
+
+ // Landscape
+ if (desired_ratio > 1.0) {
+ }
+
+ // Portrait
+ if (desired_ratio < 1.0) {
+ }
+
+
+
+ printf("%lu x %lu\n", width, height);
+
+
+ return 0;
+
+}
+
+
+
+
+// Draw month art
+int draw_month_art(cairo_t *c, struct dimensions *d, char *path) {
+ cairo_save(c);
+ double width = d->header_width;
+ // TODO: Make this relative to text height
+ double height = d->header_height - (d->margin * 3.0);
+
+ double cursor_x = d->margin;
+ double cursor_y = d->margin;
+ cairo_rectangle (c, d->margin, d->margin, width, height);
+ cairo_clip(c);
+
+
+ draw_image(c, path, cursor_x, cursor_y);
+ cairo_restore(c);
+ return 0;
+}
+
+