144 lines
3.4 KiB
C
144 lines
3.4 KiB
C
#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;
|
|
}
|