summaryrefslogtreecommitdiff
path: root/src/jpeg-utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jpeg-utils.cpp')
-rw-r--r--src/jpeg-utils.cpp115
1 files changed, 105 insertions, 10 deletions
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index 11d2c4e..aaf59fc 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -467,6 +467,37 @@ autorotate_image (MagickWand *magick_wand)
DestroyPixelWand (pixel_wand);
}
+static gchar **
+parse_cmd_args (const gchar *resize_opts, const gchar *prepend, const gchar *append, const gchar *file_in, const gchar *file_out, unsigned long size_x, unsigned long size_y)
+{
+ gchar *in;
+ gchar **s;
+ gchar *f;
+
+ in = g_strdup_printf ("%s %s %s %s %s",
+ prepend ? prepend : "",
+ file_in ? file_in : "",
+ resize_opts,
+ file_out ? file_out : "",
+ append ? append : "");
+ while (g_strstr_len (in, -1, "${WIDTH}")) {
+ f = g_strdup_printf ("%lu", size_x);
+ str_replace (&in, "${WIDTH}", f);
+ g_free (f);
+ }
+ while (g_strstr_len (in, -1, "${HEIGHT}")) {
+ f = g_strdup_printf ("%lu", size_y);
+ str_replace (&in, "${HEIGHT}", f);
+ g_free (f);
+ }
+ /* ImageMagick doesn't like empty elements */
+ str_trim_inside (&in);
+ s = g_strsplit (in, " ", -1);
+ g_free (in);
+
+ return s;
+}
+
/*
* resize_image: resize image pointed by src and save result to dst
*/
@@ -476,14 +507,20 @@ resize_image (const gchar *src, const gchar *dst,
int quality,
gboolean thumbnail,
gboolean autorotate,
- ExifData *exif)
+ ExifData *exif,
+ gchar *resize_opts)
{
MagickWand *magick_wand;
+ ImageInfo *image_info;
+ ExceptionInfo *exception_info;
ExceptionType severity;
unsigned long w, h;
unsigned long new_w, new_h;
double source_aspect, target_aspect;
gchar *description;
+ gchar **cmd_args;
+ gchar *res_id = NULL;
+ gchar *mpr_res_id;
g_assert (src != NULL);
g_assert (dst != NULL);
@@ -494,6 +531,7 @@ resize_image (const gchar *src, const gchar *dst,
description = MagickGetException (magick_wand, &severity);
log_error ("Error reading image: %s %s %ld %s\n", GetMagickModule(), description);
MagickRelinquishMemory (description);
+ DestroyMagickWand (magick_wand);
return FALSE;
}
@@ -501,10 +539,9 @@ resize_image (const gchar *src, const gchar *dst,
autorotate_image (magick_wand);
/* Don't resize if smaller than desired size */
- if (MagickGetImageWidth (magick_wand) > size_x ||
- MagickGetImageHeight (magick_wand) > size_y)
+ if (MagickGetImageWidth (magick_wand) > size_x || MagickGetImageHeight (magick_wand) > size_y)
{
- /* Process thumbnail if required */
+ /* Prepare image before resizing */
if (thumbnail) {
if (exif->thumbnail_crop_style != CROP_STYLE_NORMAL) {
w = MagickGetImageWidth (magick_wand);
@@ -548,12 +585,64 @@ resize_image (const gchar *src, const gchar *dst,
break;
}
}
- MagickThumbnailImage (magick_wand, size_x, size_y);
- /* FIXME: this strips image ICC profile, should do proper conversion first */
- MagickStripImage (magick_wand);
}
- else
- MagickResizeImage (magick_wand, size_x, size_y, LanczosFilter, 1.0);
+
+ if (resize_opts == NULL) {
+ /* Perform internal resizing */
+ if (thumbnail) {
+ MagickThumbnailImage (magick_wand, size_x, size_y);
+ } else {
+ MagickResizeImage (magick_wand, size_x, size_y, LanczosFilter, 1.0);
+ }
+ } else {
+ /* Perform resizing through ImageMagick commandline parser */
+ res_id = g_strdup_printf ("cgg_resize_image_%p", g_thread_self ());
+ mpr_res_id = g_strdup_printf ("mpr:%s", res_id);
+ if (MagickWriteImage (magick_wand, mpr_res_id) == MagickFalse) {
+ description = MagickGetException (magick_wand, &severity);
+ log_error ("Error writing mpr image: %s %s %ld %s\n", GetMagickModule(), description);
+ MagickRelinquishMemory (description);
+ DestroyMagickWand (magick_wand);
+ g_free (res_id);
+ g_free (mpr_res_id);
+ return FALSE;
+ }
+ ClearMagickWand (magick_wand);
+
+ cmd_args = parse_cmd_args (resize_opts, "convert", NULL, mpr_res_id, mpr_res_id, size_x, size_y);
+ image_info = AcquireImageInfo ();
+ g_assert (image_info != NULL);
+ exception_info = AcquireExceptionInfo ();
+ g_assert (exception_info != NULL);
+ if (MagickCommandGenesis (image_info, ConvertImageCommand, g_strv_length (cmd_args), cmd_args, NULL, exception_info) == MagickFalse) {
+ /* MagickCommandGenesis() should've printed verbose error message */
+ DestroyImageInfo (image_info);
+ DestroyExceptionInfo (exception_info);
+ DestroyMagickWand (magick_wand);
+ g_free (res_id);
+ g_free (mpr_res_id);
+ return FALSE;
+ }
+ DestroyImageInfo (image_info);
+ DestroyExceptionInfo (exception_info);
+ g_strfreev (cmd_args);
+
+ if (MagickReadImage (magick_wand, mpr_res_id) == MagickFalse) {
+ description = MagickGetException (magick_wand, &severity);
+ printf ("Error reading mpr image: %s %s %ld %s\n", GetMagickModule(), description);
+ MagickRelinquishMemory (description);
+ DestroyMagickWand (magick_wand);
+ g_free (res_id);
+ g_free (mpr_res_id);
+ return FALSE;
+ }
+ g_free (mpr_res_id);
+ }
+ }
+
+ if (thumbnail) {
+ /* FIXME: this strips image ICC profile, should do proper conversion first */
+ MagickStripImage (magick_wand);
}
if ((int) MagickGetImageCompressionQuality (magick_wand) != quality)
@@ -563,10 +652,16 @@ resize_image (const gchar *src, const gchar *dst,
if (MagickWriteImage (magick_wand, dst) == MagickFalse) {
description = MagickGetException (magick_wand, &severity);
log_error ("Error writing image: %s %s %ld %s\n", GetMagickModule(), description);
- MagickRelinquishMemory (description);
+ DeleteImageRegistry (res_id);
+ g_free (res_id);
return FALSE;
}
+ if (res_id) {
+ /* This is potentially dangerous operation - modifying ImageMagick's internal image registry */
+ DeleteImageRegistry (res_id);
+ g_free (res_id);
+ }
magick_wand = DestroyMagickWand (magick_wand);
return TRUE;