From b2d0c4ea27c3885d69c9067b579a075a65ff3834 Mon Sep 17 00:00:00 2001 From: Tomas Bzatek Date: Sun, 1 Feb 2015 16:23:30 +0100 Subject: theming: Introduce image size fallback mode This changes image size handling a little bit. An optional tag tells the generator to use different image size when an image for the current image size has not been supplied from the album XML file. This is effectively used for the legacy tag fallback. More generally this is useful for templates showing additional image sizes. Also saves space as images not having the custom size supplied are not generated from the source image. --- src/generators.c | 93 +++++++++++++++++++++++++++++++++++--------------------- src/setup.c | 31 +++++++++++++++++-- src/setup.h | 1 + 3 files changed, 87 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/generators.c b/src/generators.c index 9183888..3bd00a3 100644 --- a/src/generators.c +++ b/src/generators.c @@ -204,7 +204,7 @@ get_image_paths (TGallerySetup *setup, gboolean is_original; gchar *s1, *s2, *s3; gchar *target_image_dir; - TImageSize *preview_image_size; + TImageSize *src_image_size; if (full_img_src) *full_img_src = NULL; @@ -221,19 +221,45 @@ get_image_paths (TGallerySetup *setup, (image_size->is_thumbnail && item->hidden) || (image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX && (item->thumbnail == NULL || strlen (item->thumbnail) == 0))) return; + if (is_original && nofullsize && image_size->fallback_size == NULL) { + log_error ("Requested legacy nofullsize flag but fallback image size not defined.\n"); + return; + } s1 = NULL; if (image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX) s1 = item->thumbnail; - if (s1 == NULL && ! is_original && item->image_sizes != NULL) { + + if (s1 == NULL && ! is_original && item->image_sizes != NULL) s1 = g_hash_table_lookup (item->image_sizes, image_size->name); - } - if (s1 == NULL) + + if (s1 == NULL && is_original && ! nofullsize) s1 = item->path; - /* legacy behaviour fallback */ - if (s1 == NULL && item->image_sizes != NULL) - s1 = g_hash_table_lookup (item->image_sizes, "preview"); + /* go through the fallback */ + while (s1 == NULL && image_size->fallback_size != NULL) { + image_size = lookup_image_size_for_name (setup, image_size->fallback_size); + is_original = g_ascii_strcasecmp ("original", image_size->name) == 0; + if (is_original) + s1 = nofullsize ? NULL : item->path; + else + s1 = item->image_sizes ? g_hash_table_lookup (item->image_sizes, image_size->name) : NULL; + } + + /* we have reached our target image size, s1 == NULL means the image should be resized from the original size */ + if (s1 == NULL) { + s1 = item->path; /* nofullsize is handled by the fallback */ + if (s1 == NULL) { + /* no original image available, try fallback as a last resort (i.e. preview fallback) */ + src_image_size = lookup_image_size_for_name (setup, "original"); + while (s1 == NULL && src_image_size->fallback_size != NULL) { + src_image_size = lookup_image_size_for_name (setup, src_image_size->fallback_size); + if (item->image_sizes != NULL) + s1 = g_hash_table_lookup (item->image_sizes, src_image_size->name); + } + } + } + if (s1 == 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; @@ -242,17 +268,7 @@ get_image_paths (TGallerySetup *setup, if (full_img_src) *full_img_src = g_build_filename (path_info->src_dir, s1, NULL); - /* Use preview image for targets but leave original source if nofullsize is defined (legacy behaviour) */ - preview_image_size = NULL; - if (is_original && nofullsize && item->image_sizes != NULL) { - s2 = g_hash_table_lookup (item->image_sizes, "preview"); - if (s2 != NULL) { - s1 = s2; - preview_image_size = lookup_image_size_for_name (setup, "preview"); - } - } - target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, preview_image_size ? preview_image_size->name : image_size->name); - + 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); @@ -427,7 +443,11 @@ generate_image (TGallerySetup *setup, is_original = g_ascii_strcasecmp ("original", image_size->name) == 0; is_preview = g_ascii_strcasecmp ("preview", image_size->name) == 0; - if (is_original && IS_NOFULLSIZE (item, items, setup)) + if (is_original && (IS_NOFULLSIZE (item, items, setup) || item->path == NULL)) + continue; + + /* fallback mode, don't generate any image and use different image size */ + if (image_size->fallback_size != NULL && ! is_original && (! item->image_sizes || g_hash_table_lookup (item->image_sizes, image_size->name) == NULL)) continue; get_image_paths (setup, items, item, path_info, image_size, &img_src, &img_dst, NULL); @@ -447,7 +467,7 @@ generate_image (TGallerySetup *setup, 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 && (is_original || (item->image_sizes && g_hash_table_lookup (item->image_sizes, image_size->name)))) { + if (! image_size->is_thumbnail && image_size->no_resize && ((is_original && item->path) || (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); } @@ -771,27 +791,32 @@ get_img_exif_data (TGallerySetup *setup, if (exif == NULL) { img_orig_src = NULL; orig_image_size = lookup_image_size_for_name (setup, "original"); - get_image_paths (setup, items, item, path_info, orig_image_size ? orig_image_size : image_size, &img_orig_src, NULL, NULL); - if (img_orig_src != NULL && g_access (img_orig_src, R_OK) == 0) - exif = read_exif (img_orig_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); + if (orig_image_size) { + get_image_paths (setup, items, item, path_info, orig_image_size, &img_orig_src, NULL, NULL); + if (img_orig_src != NULL && g_access (img_orig_src, R_OK) == 0) + exif = read_exif (img_orig_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); + } } - /* Try destination image instead, though it might have the metadata stripped (as in source file already) */ + /* Try destination image size instead, though it might have the metadata stripped */ if (exif == NULL) { - img_dst = NULL; - get_image_paths (setup, items, item, path_info, image_size, NULL, &img_dst, NULL); - if (img_dst != NULL && g_access (img_dst, R_OK) == 0) + 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) 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) @@ -901,9 +926,7 @@ process_img_item (TGallerySetup *setup, /* TODO: legacy stuff, subject to removal */ orig_image_size = lookup_image_size_for_name (setup, "original"); - if (orig_image_size == NULL) - orig_image_size = image_size; - if (image_size != orig_image_size && img_orig_dst != NULL && ! IS_NOFULLSIZE (item, items, setup)) { + if (orig_image_size != NULL && img_orig_dst != NULL && ! IS_NOFULLSIZE (item, items, setup)) { 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); diff --git a/src/setup.c b/src/setup.c index 9cdf7d5..f0a6f3d 100644 --- a/src/setup.c +++ b/src/setup.c @@ -233,8 +233,8 @@ parse_design_setup_xml (const gchar *filename) image_size->quality = xml_file_get_node_attribute_long_with_default (xml, s, "value", -1); 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); + 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); } @@ -434,8 +434,10 @@ gboolean validate_design_setup (TGallerySetup *setup) { GList *l; - TImageSize *image_size; + TImageSize *image_size, *isi; TGalleryDesignTheme *theme; + GHashTable *fallback_history; + gboolean res; /* check for version match */ if (! SETUP_IS_NATIVE (setup->design)) { @@ -460,6 +462,28 @@ validate_design_setup (TGallerySetup *setup) fprintf (stderr, "design validation warning: image size %s defined with zero sized element\n", image_size->name); continue; } + if (image_size->fallback_size != NULL && lookup_image_size_for_name (setup, image_size->fallback_size) == NULL) { + fprintf (stderr, "design validation error: specified \"%s\" fallback image size not found\n", image_size->fallback_size); + return FALSE; + } + if (image_size->fallback_size != NULL) { + fallback_history = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + isi = image_size; + res = TRUE; + while (isi != NULL) { + if (g_hash_table_lookup (fallback_history, isi->name)) { + res = FALSE; + break; + } + g_hash_table_insert (fallback_history, g_strdup (isi->name), (gpointer) 0x1); + isi = lookup_image_size_for_name (setup, isi->fallback_size); + } + g_hash_table_unref (fallback_history); + if (! res) { + fprintf (stderr, "design validation error: the fallback path for the \"%s\" image size leads to an endless loop\n", image_size->name); + return FALSE; + } + } } /* validate themes */ @@ -577,6 +601,7 @@ free_image_size_data (TImageSize *image_size) if (image_size) { g_free (image_size->name); g_free (image_size->tagname); + g_free (image_size->fallback_size); g_free (image_size); } } diff --git a/src/setup.h b/src/setup.h index d772360..d34906d 100644 --- a/src/setup.h +++ b/src/setup.h @@ -105,6 +105,7 @@ typedef struct { int crop_height; int quality; gboolean no_resize; + gchar *fallback_size; TCropStyle thumb_crop_style; } TImageSize; -- cgit v1.2.3