aboutsummaryrefslogtreecommitdiff
path: root/thumbnail.c
diff options
context:
space:
mode:
Diffstat (limited to 'thumbnail.c')
-rw-r--r--thumbnail.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/thumbnail.c b/thumbnail.c
new file mode 100644
index 0000000..9e425cb
--- /dev/null
+++ b/thumbnail.c
@@ -0,0 +1,143 @@
+#include "thumbnail.h"
+#include <magick/api.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+/* http://www.graphicsmagick.org/api/api.html */
+
+int thumbnail_create(const char *const src, const char *const dst)
+{
+ int ret = -1;
+ const size_t slen = strlen(src), dlen = strlen(dst);
+ ImageInfo *info = NULL;
+ Image *i = NULL, *t = NULL;
+ ExceptionInfo exc;
+
+ InitializeMagick(NULL);
+ GetExceptionInfo(&exc);
+
+ if (slen >= sizeof i->filename)
+ {
+ fprintf(stderr, "%s: src maximum length exceeded (%zu, max %zu)\n",
+ __func__, slen, sizeof i->filename - 1);
+ goto end;
+ }
+ else if (dlen >= sizeof t->filename)
+ {
+ fprintf(stderr, "%s: dst maximum length exceeded (%zu, max %zu)\n",
+ __func__, slen, sizeof t->filename - 1);
+ goto end;
+ }
+ else if (!(info = CloneImageInfo(NULL)))
+ {
+ fprintf(stderr, "%s: CloneImageInfo failed\n", __func__);
+ goto end;
+ }
+
+ strcpy(info->filename, src);
+ info->adjoin = MagickTrue;
+
+ if (!(i = ReadImage(info, &exc)))
+ {
+ if (exc.severity == MissingDelegateError)
+ /* Non-image file format. */
+ ret = 1;
+ else
+ fprintf(stderr, "%s: ReadImage failed: "
+ "reason: %s, description: %s\n",
+ __func__, exc.reason, exc.description);
+
+ goto end;
+ }
+
+ const unsigned long y = i->rows > THUMBNAIL_HEIGHT ?
+ THUMBNAIL_HEIGHT : i->rows,
+ x = y * i->columns / i->rows;
+
+ if (!(t = ResizeImage(i, x, y, PointFilter, 1, &exc)))
+ {
+ fprintf(stderr, "%s: ResizeImage failed, "
+ "reason: %s, description: %s\n",
+ __func__, exc.reason, exc.description);
+ goto end;
+ }
+ else if (WriteImages(info, t, dst, &exc) != MagickPass)
+ {
+ fprintf(stderr, "%s: WriteImages failed, "
+ "reason: %s, description: %s\n",
+ __func__, exc.reason, exc.description);
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ DestroyImageInfo(info);
+ DestroyImage(i);
+ DestroyImage(t);
+ DestroyExceptionInfo(&exc);
+ DestroyMagick();
+ return ret;
+}
+
+bool thumbnail_configured(void)
+{
+ return true;
+}
+
+int thumbnail_dim(const char *const path, struct thumbnail_dim *const d)
+{
+ int ret = -1;
+ const size_t slen = strlen(path);
+ ImageInfo *info = NULL;
+ Image *i = NULL;
+ ExceptionInfo exc;
+
+ InitializeMagick(NULL);
+ GetExceptionInfo(&exc);
+
+ if (slen >= sizeof i->filename)
+ {
+ fprintf(stderr, "%s: src maximum length exceeded (%zu, max %zu)\n",
+ __func__, slen, sizeof i->filename - 1);
+ goto end;
+ }
+ else if (!(info = CloneImageInfo(NULL)))
+ {
+ fprintf(stderr, "%s: CloneImageInfo failed\n", __func__);
+ goto end;
+ }
+
+ strcpy(info->filename, path);
+ info->adjoin = MagickTrue;
+
+ if (!(i = ReadImage(info, &exc)))
+ {
+ if (exc.severity == MissingDelegateError)
+ /* Non-image file format. */
+ ret = 1;
+ else
+ fprintf(stderr, "%s: ReadImage failed: "
+ "reason: %s, description: %s\n",
+ __func__, exc.reason, exc.description);
+
+ goto end;
+ }
+
+ *d = (const struct thumbnail_dim)
+ {
+ .w = i->columns,
+ .h = i->rows
+ };
+
+ ret = 0;
+
+end:
+ DestroyImageInfo(info);
+ DestroyImage(i);
+ DestroyExceptionInfo(&exc);
+ DestroyMagick();
+ return ret;
+}