summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2016-09-18 19:34:56 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2016-09-18 19:54:08 +0200
commitaeefd1959aad3b80a0fe02083edbd5ebfb09510b (patch)
tree4da69339f39f55c3a70e7f54a4eafe95ea9fd972 /src
parent6b853ad4312763d50f1e843d4e7168ccd023530a (diff)
downloadcataract-aeefd1959aad3b80a0fe02083edbd5ebfb09510b.tar.xz
Introduce resizing thresholds
This commit brings deeper changes to the image sizes concept. The goal was to allow more flexible input in resizing vs. supplied files mixed mode. Instead of hard <noresize> flags the decision whether to resize or copy an image is now based on threshold. While not 100% universal, it brings more control regarding image size bounds. Also brings a level of tolerance for specific errors (off-by-one exports). Image sizes' rules are a bit simpler, hopefully easier to understand. A lot can be achieved by combination of thresholds.
Diffstat (limited to 'src')
-rw-r--r--src/generators.c322
-rw-r--r--src/items.c19
-rw-r--r--src/items.h5
-rw-r--r--src/jpeg-utils.cpp8
-rw-r--r--src/jpeg-utils.h1
-rw-r--r--src/setup.c17
-rw-r--r--src/setup.h8
7 files changed, 248 insertions, 132 deletions
diff --git a/src/generators.c b/src/generators.c
index 1ecb3c6..b9df04c 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -186,80 +186,107 @@ get_item_titles (TGallerySetup *setup,
*title_desc = g_strstrip (*title_desc);
}
-static void
-get_image_paths (TGallerySetup *setup,
- TAlbum *items,
- TIndexItem *item,
- TPathInfo *path_info,
- TImageSize *image_size,
- gchar **full_img_src,
- gchar **full_img_dst,
- gchar **page_img_dst)
+static gchar *
+get_image_source_path (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ TPathInfo *path_info,
+ TImageSize *image_size)
{
- gchar *s1, *s2, *s3;
- gchar *target_image_dir;
-
- if (full_img_src)
- *full_img_src = NULL;
- if (full_img_dst)
- *full_img_dst = NULL;
- if (page_img_dst)
- *page_img_dst = NULL;
-
- if (full_img_src == NULL && image_size == NULL)
- return;
+ const gchar *s;
- s1 = NULL;
+ s = NULL;
/* image_size == NULL means return real image source path */
if (image_size) {
/* ignore combinations that are not valid */
if ((items->type == GALLERY_TYPE_INDEX && ! image_size->is_thumbnail) ||
(image_size->is_thumbnail && item->hidden) ||
(image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX && (item->thumbnail == NULL || strlen (item->thumbnail) == 0)))
- return;
+ return NULL;
if (image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX)
- s1 = item->thumbnail;
+ s = item->thumbnail;
- if (s1 == NULL && item->image_sizes != NULL)
- s1 = g_hash_table_lookup (item->image_sizes, image_size->name);
-
- /* go through the fallback */
- while (s1 == NULL && image_size->fallback_size != NULL) {
- image_size = lookup_image_size_for_name (setup, image_size->fallback_size);
- s1 = item->image_sizes ? g_hash_table_lookup (item->image_sizes, image_size->name) : NULL;
- }
+ if (s == NULL && item->image_sizes != NULL)
+ s = g_hash_table_lookup (item->image_sizes, image_size->name);
}
- /* we have reached our target image size, s1 == NULL means the image should be resized from the source image */
- if (s1 == NULL)
- s1 = item->path;
+ /* we have reached our target image size, s == NULL means the image should be resized from the source image */
+ if (s == NULL)
+ s = item->path;
- if (s1 == NULL) {
+ if (s == NULL) {
log_error ("Unable to find image source for item #%d (\"%s\") for image size \"%s\"\n", get_item_index (items, item), item->title, image_size->name);
- return;
+ return NULL;
}
- if (full_img_src)
- *full_img_src = g_build_filename (path_info->src_dir, s1, NULL);
+ return g_build_filename (path_info->src_dir, s, NULL);
+}
- if (image_size) {
- target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, image_size->name);
- s2 = g_path_get_basename (s1);
- if (image_size->is_thumbnail) {
- s3 = g_strdup_printf (THUMBNAIL_NAME_FORMAT, get_item_index (items, item), s2);
- g_free (s2);
- s2 = s3;
- }
- if (full_img_dst)
- *full_img_dst = g_build_filename (path_info->dest_dir, target_image_dir, s2, NULL);
- if (page_img_dst)
- *page_img_dst = g_build_filename (target_image_dir, s2, NULL);
- g_free (s2);
- g_free (target_image_dir);
+static gchar *
+get_image_dest_path (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ TPathInfo *path_info,
+ TImageSize *image_size,
+ gboolean page_link)
+{
+ gchar *src;
+ gchar *dst;
+ gchar *s, *s2;
+ gchar *target_image_dir;
+
+ g_assert (image_size != NULL);
+
+ src = get_image_source_path (setup, items, item, path_info, image_size);
+
+ target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, image_size->name);
+ s = g_path_get_basename (src);
+ if (image_size->is_thumbnail) {
+ s2 = g_strdup_printf (THUMBNAIL_NAME_FORMAT, get_item_index (items, item), s);
+ g_free (s);
+ s = s2;
}
+ if (page_link)
+ dst = g_build_filename (target_image_dir, s, NULL);
+ else
+ dst = g_build_filename (path_info->dest_dir, target_image_dir, s, NULL);
+
+ g_free (s);
+ g_free (target_image_dir);
+ g_free (src);
+
+ return dst;
}
+static gchar *
+get_image_dest_path_with_fallback (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ TPathInfo *path_info,
+ TImageSize *image_size,
+ gboolean page_link)
+{
+ gchar *dst;
+ TImageSize *tmp_image_size;
+
+ if (image_size->fallback_size == NULL)
+ return get_image_dest_path (setup, items, item, path_info, image_size, page_link);
+
+ tmp_image_size = image_size;
+ while ((dst = get_image_dest_path (setup, items, item, path_info, tmp_image_size, FALSE)),
+ tmp_image_size->fallback_size && g_access (dst, R_OK) != 0) {
+ g_free (dst);
+ tmp_image_size = lookup_image_size_for_name (setup, tmp_image_size->fallback_size);
+ }
+
+ if (page_link) {
+ g_free (dst);
+ dst = get_image_dest_path (setup, items, item, path_info, tmp_image_size, page_link);
+ }
+
+ return dst;
+}
static void
metadata_apply_overrides (ExifData *exif_data,
@@ -330,40 +357,61 @@ struct HaveImageSizeData {
TGallerySetup *setup;
TAlbum *items;
TIndexItem *item;
+ TPathInfo *path_info;
};
static gboolean
+have_generated_image (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ TPathInfo *path_info,
+ TImageSize *image_size)
+{
+ gchar *img_dst;
+ int res;
+
+ img_dst = get_image_dest_path (setup, items, item, path_info, image_size, FALSE);
+ if (img_dst == NULL)
+ return FALSE;
+ res = g_access (img_dst, R_OK);
+ g_free (img_dst);
+
+ return (res == 0);
+}
+
+static gboolean
have_image_size_cb (gchar **args, gpointer user_data)
{
struct HaveImageSizeData *data = user_data;
+ TImageSize *image_size;
g_return_val_if_fail (g_strv_length (args) != 2, FALSE); /* incl. trailing NULL */
/* no image size of that name available */
- if (! lookup_image_size_for_name (data->setup, *args))
+ image_size = lookup_image_size_for_name (data->setup, *args);
+ if (image_size == NULL)
return FALSE;
if (data->item->image_sizes && g_hash_table_lookup (data->item->image_sizes, *args))
return TRUE;
- /* FIXME: rework this */
-/* if (data->item->path)
- return TRUE; */
-
- return FALSE;
+ /* check for generated image */
+ return have_generated_image (data->setup, data->items, data->item, data->path_info, image_size);
}
static gboolean
have_album_image_size_cb (gchar **args, gpointer user_data)
{
struct HaveImageSizeData *data = user_data;
+ TImageSize *image_size;
TIndexItem *iter_item;
int i;
g_return_val_if_fail (g_strv_length (args) != 2, FALSE); /* incl. trailing NULL */
/* no image size of that name available */
- if (! lookup_image_size_for_name (data->setup, *args))
+ image_size = lookup_image_size_for_name (data->setup, *args);
+ if (image_size == NULL)
return FALSE;
for (i = 0; i < data->items->items->len; i++) {
@@ -374,9 +422,9 @@ have_album_image_size_cb (gchar **args, gpointer user_data)
if (iter_item->image_sizes && g_hash_table_lookup (iter_item->image_sizes, *args))
return TRUE;
- /* FIXME: rework this */
-/* if (iter_item->path)
- return TRUE; */
+ /* check for generated image */
+ if (have_generated_image (data->setup, data->items, iter_item, data->path_info, image_size))
+ return TRUE;
}
return FALSE;
@@ -399,6 +447,7 @@ generate_image (TGallerySetup *setup,
unsigned long img_w, img_h;
unsigned long src_img_w, src_img_h;
unsigned long tmpw, tmph;
+ int src_img_quality, img_quality;
GList *l;
TImageSize *image_size;
ExifData *exif_data;
@@ -408,19 +457,20 @@ generate_image (TGallerySetup *setup,
for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) {
image_size = l->data;
- /* fallback mode, don't generate any image and use different image size */
- if (image_size->fallback_size != NULL && (item->image_sizes == NULL || g_hash_table_lookup (item->image_sizes, image_size->name) == NULL))
+ img_src = get_image_source_path (setup, items, item, path_info, image_size);
+ if (img_src == NULL)
continue;
-
- get_image_paths (setup, items, item, path_info, image_size, &img_src, &img_dst, NULL);
- if (img_src == NULL || img_dst == NULL)
- continue;
-
if (g_access (img_src, R_OK) != 0) {
log_error (" Error opening image %s for size \"%s\": %s\n", img_src, image_size->name, g_strerror (errno));
+ g_free (img_src);
res = TRUE;
continue;
}
+ img_dst = get_image_dest_path (setup, items, item, path_info, image_size, FALSE);
+ if (img_dst == NULL) {
+ g_free (img_src);
+ continue;
+ }
exif_data = exif_data_new_empty ();
metadata_apply_overrides (exif_data, setup, path_info, items, item, image_size);
@@ -428,17 +478,16 @@ generate_image (TGallerySetup *setup,
/* Do something when required */
res = res || needs_update (img_src, img_dst);
if (! query_update) {
- /* Determine whether to perform file copy or resize */
- if (! image_size->is_thumbnail && image_size->no_resize && (! item->image_sizes || (item->image_sizes && g_hash_table_lookup (item->image_sizes, image_size->name)))) {
+ /* Always copy supplied image size */
+ if (! image_size->is_thumbnail && item->image_sizes && g_hash_table_lookup (item->image_sizes, image_size->name)) {
if (! copy_file (img_src, img_dst))
log_error (" Error copying image %s to %s\n", img_src, img_dst);
}
/* Resize image */
else {
- get_image_sizes (img_src, &src_img_w, &src_img_h, setup->autorotate);
+ get_image_sizes (img_src, &src_img_w, &src_img_h, &src_img_quality, setup->autorotate);
if (src_img_w > 0 && src_img_h > 0) {
- stats_images_inc ();
-
+ img_quality = image_size->quality;
if (image_size->is_thumbnail && image_size->thumb_crop_style != CROP_STYLE_NORMAL) {
switch (image_size->thumb_crop_style) {
case CROP_STYLE_SQUARED:
@@ -463,14 +512,41 @@ generate_image (TGallerySetup *setup,
tmpw = image_size->portrait_width;
tmph = image_size->portrait_height;
}
- calculate_sizes (tmpw, tmph, &img_w, &img_h);
+ /* Check for image size suitability */
+ if (! image_size->is_thumbnail && src_img_w + image_size->availability_threshold < tmpw && src_img_h + image_size->availability_threshold < tmph) {
+/* printf (" Warning: source image %s (%lux%lu) is not large enough for the \"%s\" image size (need %lux%lu)\n", img_src, src_img_w, src_img_h, image_size->name, tmpw, tmph); */
+ g_free (img_src);
+ g_free (img_dst);
+ continue;
+ }
+ /* Calculate dimensions */
+ if (src_img_w < tmpw + image_size->no_resize_threshold && src_img_h < tmph + image_size->no_resize_threshold) {
+/* printf (" Note: image %s dimensions (%lux%lu) are within bounds (%lux%lu..%lux%lu), passing by...\n",
+ img_src, src_img_w, src_img_h, tmpw - image_size->availability_threshold, tmph - image_size->availability_threshold,
+ tmpw + image_size->no_resize_threshold, tmph + image_size->no_resize_threshold); */
+ } else {
+ calculate_sizes (tmpw, tmph, &img_w, &img_h);
+ if (setup->warn_resize)
+ printf (" Warning: resizing image %s from %lux%lu to %lux%lu\n", img_src, src_img_w, src_img_h, img_w, img_h);
+ }
+ /* Calculate compression quality */
+ if (src_img_quality >= image_size->quality + image_size->quality_threshold) {
+ if (setup->warn_resize)
+ printf (" Warning: lowering compression quality of %s from %d to %d\n", img_src, src_img_quality, img_quality);
+ } else {
+ img_quality = src_img_quality;
+ }
}
/* Perform resize and strip */
- if (setup->warn_resize && ! image_size->is_thumbnail)
- printf (" Warning: resizing image %s from %lux%lu to %lux%lu\n", img_src, src_img_w, src_img_h, img_w, img_h);
- if (! resize_image (img_src, img_dst, img_w, img_h, image_size->quality, image_size->is_thumbnail, setup->autorotate, exif_data))
- log_error (" Error resizing image %s\n", img_src);
+ stats_images_inc ();
+ if (src_img_w == img_w && src_img_h == img_h && src_img_quality == img_quality) {
+ if (! copy_file (img_src, img_dst))
+ log_error (" Error copying image %s to %s\n", img_src, img_dst);
+ } else {
+ if (! resize_image (img_src, img_dst, img_w, img_h, img_quality, image_size->is_thumbnail, setup->autorotate, exif_data))
+ log_error (" Error resizing image %s\n", img_src);
+ }
} else {
log_error ("generate_image: image %s sizes are %lux%lu\n", img_src, src_img_w, src_img_h);
}
@@ -671,7 +747,6 @@ add_next_prev_links (TGallerySetup *setup,
int item_index;
int i;
gchar *s;
- gchar *preload_imgname;
item_index = get_item_index (items, item);
for (i = item_index - 2; i >= 0; i--) {
@@ -705,10 +780,11 @@ add_next_prev_links (TGallerySetup *setup,
else
replace_table_add_key (replace_table, "LINK_PREV", get_index_filename (items, theme, NULL, NULL));
- if (next_item != NULL && setup->preload && image_size != NULL) {
- get_image_paths (setup, items, next_item, path_info, image_size, NULL, NULL, &preload_imgname);
- }
- replace_table_add_key (replace_table, "IMG_SRC_PRELOAD", preload_imgname ? preload_imgname : "");
+ s = NULL;
+ if (next_item != NULL && setup->preload && image_size != NULL)
+ s = get_image_dest_path_with_fallback (setup, items, next_item, path_info, image_size, TRUE);
+ replace_table_add_key (replace_table, "IMG_SRC_PRELOAD", s ? s : "");
+ g_free (s);
}
static ExifData *
@@ -719,7 +795,7 @@ get_img_exif_data (TGallerySetup *setup,
TImageSize *image_size)
{
ExifData *exif;
- gchar *img_orig_src;
+ gchar *img_src;
gchar *img_dst;
gchar *s;
@@ -735,31 +811,29 @@ get_img_exif_data (TGallerySetup *setup,
/* Get EXIF data from the source image */
if (exif == NULL) {
- img_orig_src = NULL;
- get_image_paths (setup, items, item, path_info, NULL, &img_orig_src, NULL, NULL);
- if (img_orig_src != NULL && g_access (img_orig_src, R_OK) == 0)
- exif = read_exif (img_orig_src);
+ img_src = get_image_source_path (setup, items, item, path_info, NULL);
+ if (img_src != NULL && g_access (img_src, R_OK) == 0)
+ exif = read_exif (img_src);
/* -- silently succeed
if (exif == NULL)
log_error ("write_html_image: error getting exif data from file \"%s\"\n", img_orig_src);
*/
- g_free (img_orig_src);
+ g_free (img_src);
}
+ /* Try supplied image file */
+ if (exif == NULL && item->image_sizes != NULL) {
+ img_src = get_image_source_path (setup, items, item, path_info, image_size);
+ if (img_src != NULL && g_access (img_src, R_OK) == 0)
+ exif = read_exif (img_src);
+ g_free (img_src);
+ }
/* Try destination image size instead, though it might have the metadata stripped */
if (exif == NULL) {
- img_orig_src = img_dst = NULL;
- get_image_paths (setup, items, item, path_info, image_size, &img_orig_src, &img_dst, NULL);
- if (img_orig_src != NULL && g_access (img_orig_src, R_OK) == 0)
- exif = read_exif (img_orig_src);
- if (exif == NULL && img_dst != NULL && g_access (img_dst, R_OK) == 0)
+ img_dst = get_image_dest_path (setup, items, item, path_info, image_size, FALSE);
+ if (img_dst != NULL && g_access (img_dst, R_OK) == 0)
exif = read_exif (img_dst);
- /* -- silently succeed
- if (exif == NULL)
- log_error ("write_html_image: error getting exif data from file \"%s\"\n", img_dst);
- */
g_free (img_dst);
- g_free (img_orig_src);
}
if (exif != NULL)
@@ -790,10 +864,8 @@ process_img_item (TGallerySetup *setup,
gchar *s1, *s2, *s3, *s4;
gchar *img_dst;
gchar *img_dst_page;
- gchar *img_orig_dst;
- gchar *img_orig_dst_page;
gchar *title, *title_desc;
- TImageSize *orig_image_size;
+ TImageSize *tmp_image_size;
ExifData *exif = NULL;
struct HaveImageSizeData *img_size_data;
@@ -822,12 +894,13 @@ process_img_item (TGallerySetup *setup,
g_free (s1);
}
else {
- get_image_paths (setup, items, item, path_info, thumb_image_size, NULL, &s2, &s3);
+ s2 = get_image_dest_path (setup, items, item, path_info, thumb_image_size, FALSE);
+ s3 = get_image_dest_path (setup, items, item, path_info, thumb_image_size, TRUE);
}
img_thumb_w = img_thumb_h = 0;
if (s2 != NULL)
- get_image_sizes (s2, &img_thumb_w, &img_thumb_h, setup->autorotate);
+ get_image_sizes (s2, &img_thumb_w, &img_thumb_h, NULL, setup->autorotate);
if (img_thumb_w == img_thumb_h)
replace_table_add_key (replace_table, "THUMB_ORIENTATION", "squared");
@@ -856,36 +929,35 @@ process_img_item (TGallerySetup *setup,
/* Image stuff */
if (image_size != NULL) {
/* First calculate image paths */
- img_dst = img_dst_page = NULL;
- get_image_paths (setup, items, item, path_info, image_size, NULL, &img_dst, &img_dst_page);
+ img_dst = get_image_dest_path_with_fallback (setup, items, item, path_info, image_size, FALSE);
+ img_dst_page = get_image_dest_path_with_fallback (setup, items, item, path_info, image_size, TRUE);
/* Retrieve image sizes */
- get_image_sizes (img_dst, &img_w, &img_h, setup->autorotate);
+ get_image_sizes (img_dst, &img_w, &img_h, NULL, setup->autorotate);
+ exif = get_img_exif_data (setup, path_info, items, item, image_size);
replace_table_add_key_int (replace_table, "IMG_SIZE_W", img_w);
replace_table_add_key_int (replace_table, "IMG_SIZE_H", img_h);
replace_table_add_key (replace_table, "IMG_SRC", img_dst_page);
- exif = get_img_exif_data (setup, path_info, items, item, image_size);
+ g_free (img_dst);
+ g_free (img_dst_page);
- /* TODO: legacy stuff, subject to removal */
- orig_image_size = NULL;
+ /* Legacy stuff, subject to removal */
+ tmp_image_size = NULL;
/* Take the last image size from the sorted list */
if (g_list_length (setup->design->image_sizes) > 0)
- orig_image_size = (TImageSize *) g_list_last (setup->design->image_sizes);
- if (orig_image_size != NULL) {
- img_orig_dst = img_orig_dst_page = NULL;
- get_image_paths (setup, items, item, path_info, orig_image_size, NULL, &img_orig_dst, &img_orig_dst_page);
- get_image_sizes (img_orig_dst, &img_orig_w, &img_orig_h, setup->autorotate);
+ tmp_image_size = (TImageSize *) (g_list_last (setup->design->image_sizes))->data;
+ if (tmp_image_size != NULL && tmp_image_size != image_size) {
+ img_dst = get_image_dest_path_with_fallback (setup, items, item, path_info, tmp_image_size, FALSE);
+ img_dst_page = get_image_dest_path_with_fallback (setup, items, item, path_info, tmp_image_size, TRUE);
+ get_image_sizes (img_dst, &img_orig_w, &img_orig_h, NULL, setup->autorotate);
g_hash_table_replace (defines, g_strdup ("HAVE_FULLSIZE"), g_strdup (""));
replace_table_add_key_int (replace_table, "IMG_SIZE_FULLSIZE_W", img_orig_w);
replace_table_add_key_int (replace_table, "IMG_SIZE_FULLSIZE_H", img_orig_h);
- replace_table_add_key (replace_table, "IMG_SRC_FULLSIZE", img_orig_dst_page);
- g_free (img_orig_dst);
- g_free (img_orig_dst_page);
+ replace_table_add_key (replace_table, "IMG_SRC_FULLSIZE", img_dst_page);
+ g_free (img_dst);
+ g_free (img_dst_page);
}
-
- g_free (img_dst);
- g_free (img_dst_page);
}
/* Get title and description from IPTC/EXIF/JPEG if not defined */
@@ -928,8 +1000,9 @@ process_img_item (TGallerySetup *setup,
/* Single image size callback */
img_size_data = g_new0 (struct HaveImageSizeData, 1);
img_size_data->setup = setup;
- img_size_data->item = item;
img_size_data->items = items;
+ img_size_data->item = item;
+ img_size_data->path_info = path_info;
block_parser_register_function (block_parser, "have_image_size", have_image_size_cb, img_size_data, g_free);
}
@@ -1048,6 +1121,7 @@ write_html_page (TGallerySetup *setup,
img_size_data = g_new0 (struct HaveImageSizeData, 1);
img_size_data->setup = setup;
img_size_data->items = items;
+ img_size_data->path_info = path_info;
block_parser_register_function (block_parser, "have_album_image_size", have_album_image_size_cb, img_size_data, g_free);
/* Picture page tags */
diff --git a/src/items.c b/src/items.c
index d475f91..0ddc3b1 100644
--- a/src/items.c
+++ b/src/items.c
@@ -551,6 +551,25 @@ get_child_gallery_type (const gchar *filename)
}
/*
+ * dup_path_info: duplicate pathinfo data
+ */
+TPathInfo *
+dup_path_info (TPathInfo *path_info)
+{
+ TPathInfo *info;
+
+ info = g_malloc0 (sizeof (TPathInfo));
+ info->album_path = g_strdup (path_info->album_path);
+ info->dest_dir = g_strdup (path_info->dest_dir);
+ info->dest_root = g_strdup (path_info->dest_root);
+ info->source_root = g_strdup (path_info->source_root);
+ info->src_dir = g_strdup (path_info->src_dir);
+ info->templates_root = g_strdup (path_info->templates_root);
+
+ return info;
+}
+
+/*
* free_path_info: free allocated pathinfo data
*/
void
diff --git a/src/items.h b/src/items.h
index 2d0df59..24a521f 100644
--- a/src/items.h
+++ b/src/items.h
@@ -127,6 +127,11 @@ void get_album_titles (const gchar *filename, gchar **title, gchar **description
TGalleryType get_child_gallery_type (const gchar *filename);
/*
+ * dup_path_info: duplicate pathinfo data
+ */
+TPathInfo * dup_path_info (TPathInfo *path_info);
+
+/*
* free_path_info: free allocated pathinfo data
*/
void free_path_info (TPathInfo *path_info);
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index ddac2c7..11d2c4e 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -556,7 +556,8 @@ resize_image (const gchar *src, const gchar *dst,
MagickResizeImage (magick_wand, size_x, size_y, LanczosFilter, 1.0);
}
- MagickSetImageCompressionQuality (magick_wand, quality);
+ if ((int) MagickGetImageCompressionQuality (magick_wand) != quality)
+ MagickSetImageCompressionQuality (magick_wand, quality);
/* Write the image and destroy it. */
if (MagickWriteImage (magick_wand, dst) == MagickFalse) {
@@ -578,6 +579,7 @@ resize_image (const gchar *src, const gchar *dst,
void
get_image_sizes (const gchar *img,
unsigned long *width, unsigned long *height,
+ int *quality,
gboolean autorotate)
{
MagickWand *magick_wand;
@@ -587,6 +589,8 @@ get_image_sizes (const gchar *img,
*width = -1;
*height = -1;
+ if (quality)
+ *quality = -1;
g_assert (img != NULL);
@@ -610,6 +614,8 @@ get_image_sizes (const gchar *img,
*width = MagickGetImageWidth (magick_wand);
*height = MagickGetImageHeight (magick_wand);
+ if (quality)
+ *quality = (int) MagickGetImageCompressionQuality (magick_wand);
magick_wand = DestroyMagickWand (magick_wand);
}
diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h
index 3c56eaf..405d9b0 100644
--- a/src/jpeg-utils.h
+++ b/src/jpeg-utils.h
@@ -107,6 +107,7 @@ gboolean resize_image (const gchar *src, const gchar *dst,
*/
void get_image_sizes (const gchar *img,
unsigned long *width, unsigned long *height,
+ int *quality,
gboolean autorotate);
/*
diff --git a/src/setup.c b/src/setup.c
index b2cd800..7b59030 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -152,7 +152,7 @@ image_sizes_compare_func (TImageSize *a, TImageSize *b)
sa = a->landscape_width + a->landscape_height + a->portrait_width + a->portrait_height + a->square_size;
sb = b->landscape_width + b->landscape_height + b->portrait_width + b->portrait_height + b->square_size;
- return sb - sa;
+ return sa - sb;
}
/*
@@ -218,10 +218,6 @@ parse_design_setup_xml (const gchar *filename)
}
g_free (s);
- s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/no_resize", i + 1);
- image_size->no_resize = xml_file_get_node_present (xml, s);
- g_free (s);
-
s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/landscape", i + 1);
image_size->landscape_width = xml_file_get_node_attribute_long_with_default (xml, s, "w", 0);
image_size->landscape_height = xml_file_get_node_attribute_long_with_default (xml, s, "h", 0);
@@ -248,6 +244,13 @@ parse_design_setup_xml (const gchar *filename)
s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/fallback", i + 1);
image_size->fallback_size = xml_file_get_node_attribute (xml, s, "size");
g_free (s);
+
+ s = g_strdup_printf ("/design_setup/image_sizes/size[%d]/threshold", i + 1);
+ image_size->no_resize_threshold = xml_file_get_node_attribute_long_with_default (xml, s, "no_resize", DEFAULT_NO_RESIZE_THRESHOLD);
+ image_size->availability_threshold = xml_file_get_node_attribute_long_with_default (xml, s, "availability", DEFAULT_AVAILABILITY_THRESHOLD);
+ image_size->quality_threshold = xml_file_get_node_attribute_long_with_default (xml, s, "quality", DEFAULT_QUALITY_THRESHOLD);
+ g_free (s);
+
}
design->image_sizes = g_list_sort (design->image_sizes, (GCompareFunc) image_sizes_compare_func);
@@ -368,7 +371,9 @@ makeup_legacy_design (const gchar *filename)
image_size->portrait_height = xml_file_get_node_attribute_long_with_default (xml, s, "portrait_h", 0);
image_size->square_size = xml_file_get_node_attribute_long_with_default (xml, s, "square", 0);
image_size->quality = xml_file_get_node_attribute_long_with_default (xml, s, "quality", -1);
- image_size->no_resize = (i != 0);
+ image_size->no_resize_threshold = DEFAULT_NO_RESIZE_THRESHOLD;
+ image_size->availability_threshold = DEFAULT_AVAILABILITY_THRESHOLD;
+ image_size->quality_threshold = DEFAULT_QUALITY_THRESHOLD;
image_size->is_thumbnail = (i == 0);
image_size->thumb_crop_style = ((i == 0) && squared_thumbs) ? CROP_STYLE_SQUARED : CROP_STYLE_NORMAL;
g_free (s);
diff --git a/src/setup.h b/src/setup.h
index faf02f6..54b89b2 100644
--- a/src/setup.h
+++ b/src/setup.h
@@ -27,6 +27,10 @@ G_BEGIN_DECLS
#define THUMBNAIL_NAME_FORMAT "%.3d_%s"
#define TARGET_IMAGE_DIR_PREFIX "_"
+#define DEFAULT_NO_RESIZE_THRESHOLD 1
+#define DEFAULT_AVAILABILITY_THRESHOLD 1
+#define DEFAULT_QUALITY_THRESHOLD 5
+
#define SETUP_XML "setup.xml"
#define SETUP_V2_XML "setup2.xml"
#define SETUP_NATIVE_VERSION 200 /* 2.0 */
@@ -104,8 +108,10 @@ typedef struct {
int crop_width;
int crop_height;
int quality;
- gboolean no_resize;
gchar *fallback_size;
+ int no_resize_threshold;
+ int availability_threshold;
+ int quality_threshold;
TCropStyle thumb_crop_style;
} TImageSize;