diff options
Diffstat (limited to 'src/generators.c')
| -rw-r--r-- | src/generators.c | 194 |
1 files changed, 129 insertions, 65 deletions
diff --git a/src/generators.c b/src/generators.c index 72c51fb..d6984be 100644 --- a/src/generators.c +++ b/src/generators.c @@ -21,6 +21,7 @@ #include <errno.h> #include <sys/stat.h> #include <unistd.h> +#include <math.h> #include <glib.h> #include <glib/gstdio.h> @@ -207,7 +208,7 @@ get_image_source_path (TGallerySetup *setup, if (image_size->is_thumbnail && items->type == GALLERY_TYPE_INDEX) s = item->thumbnail; - if (s == NULL && item->image_sizes != NULL) + if (s == NULL && ! image_size->is_hidpi && item->image_sizes != NULL) s = g_hash_table_lookup (item->image_sizes, image_size->name); } @@ -239,6 +240,8 @@ get_image_dest_path (TGallerySetup *setup, g_assert (image_size != NULL); src = get_image_source_path (setup, items, item, path_info, image_size); + if (src == NULL) + return NULL; target_image_dir = g_strdup_printf ("%s%s", TARGET_IMAGE_DIR_PREFIX, image_size->name); s = g_path_get_basename (src); @@ -275,7 +278,7 @@ get_image_dest_path_with_fallback (TGallerySetup *setup, 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) { + tmp_image_size->fallback_size && dst != NULL && g_access (dst, R_OK) != 0) { g_free (dst); tmp_image_size = lookup_image_size_for_name (setup, tmp_image_size->fallback_size); } @@ -431,63 +434,87 @@ have_album_image_size_cb (gchar **args, gpointer user_data) } -/* - * generate_image: generate needed image sizes - */ -gboolean -generate_image (TGallerySetup *setup, - TAlbum *items, - TIndexItem *item, - TPathInfo *path_info, - gboolean query_update) +static gboolean +generate_image_for_size (TGallerySetup *setup, + TAlbum *items, + TIndexItem *item, + TPathInfo *path_info, + TImageSize *image_size, + gboolean query_update) { gboolean res; gchar *img_src; gchar *img_dst; + gchar *img_ref_dst; unsigned long img_w, img_h; unsigned long src_img_w, src_img_h; unsigned long tmpw, tmph; + unsigned long ref_img_w, ref_img_h; int src_img_quality, img_quality; - GList *l; - TImageSize *image_size; ExifData *exif_data; - res = ! query_update; - for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) { - image_size = l->data; - img_src = get_image_source_path (setup, items, item, path_info, image_size); - if (img_src == 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; - } + img_src = get_image_source_path (setup, items, item, path_info, image_size); + if (img_src == NULL) + return res; + 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); + return query_update; + } + img_dst = get_image_dest_path (setup, items, item, path_info, image_size, FALSE); + if (img_dst == NULL) { + g_free (img_src); + return res; + } - exif_data = exif_data_new_empty (); - metadata_apply_overrides (exif_data, setup, path_info, items, item, image_size); + exif_data = exif_data_new_empty (); + metadata_apply_overrides (exif_data, setup, path_info, items, item, image_size); - /* Do something when required */ - res = res || needs_update (img_src, img_dst); - if (! query_update) { - /* 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, &src_img_quality, setup->autorotate); - if (src_img_w > 0 && src_img_h > 0) { - img_quality = image_size->quality; + /* Do something when required */ + res = res || needs_update (img_src, img_dst); + if (! query_update) { + /* Always copy supplied image size */ + if (! image_size->is_thumbnail && ! image_size->is_hidpi && 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, &src_img_quality, setup->autorotate); + if (src_img_w > 0 && src_img_h > 0) { + img_quality = image_size->quality; + if (image_size->is_hidpi) { + /* Get reference regular size image dimensions */ + img_ref_dst = get_image_dest_path (setup, items, item, path_info, image_size->hidpi_ref_size, FALSE); + if (! img_ref_dst) { + g_free (img_src); + g_free (img_dst); + return res; + } + ref_img_w = ref_img_h = 0; + get_image_sizes (img_ref_dst, &ref_img_w, &ref_img_h, NULL, FALSE); + g_free (img_ref_dst); + if (ref_img_w <= 0 || ref_img_h <= 0) { + g_free (img_src); + g_free (img_dst); + return res; + } + /* Browsers need exactly n-factor of the original size */ + img_w = lround ((gdouble) ref_img_w * image_size->hidpi_scale_factor); + img_h = lround ((gdouble) ref_img_h * image_size->hidpi_scale_factor); + if ((gdouble) img_w * (100 - setup->design->hidpi_upscale_threshold) / 100 > src_img_w || (gdouble) img_h * (100 - setup->design->hidpi_upscale_threshold) / 100 > src_img_h) { +/* g_print (" 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, img_w, img_h); */ + g_free (img_src); + g_free (img_dst); + return res; + } + if (setup->warn_resize && (img_w > src_img_w || img_h > src_img_h)) + printf (" Warning: upscaling image %s from %lux%lu to %lux%lu\n", img_src, src_img_w, src_img_h, img_w, img_h); + + } else { + /* Not a HiDPI image size */ if (image_size->is_thumbnail && image_size->thumb_crop_style != CROP_STYLE_NORMAL) { switch (image_size->thumb_crop_style) { case CROP_STYLE_SQUARED: @@ -517,7 +544,7 @@ generate_image (TGallerySetup *setup, /* 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; + return res; } /* Calculate dimensions */ if (src_img_w < tmpw + image_size->no_resize_threshold && src_img_h < tmph + image_size->no_resize_threshold) { @@ -537,29 +564,66 @@ generate_image (TGallerySetup *setup, img_quality = src_img_quality; } } + } - /* Perform resize and strip */ - 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, - image_size->is_thumbnail ? setup->design->imgmagick_thumb_opts : setup->design->imgmagick_resize_opts)) - log_error (" Error resizing image %s\n", img_src); - } + + /* Perform resize and strip */ + 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 { - log_error ("generate_image: image %s sizes are %lux%lu\n", img_src, src_img_w, src_img_h); + if (! resize_image (img_src, img_dst, img_w, img_h, img_quality, image_size->is_thumbnail, setup->autorotate, image_size->is_hidpi, exif_data, + image_size->is_thumbnail ? setup->design->imgmagick_thumb_opts : setup->design->imgmagick_resize_opts)) + log_error (" Error resizing image %s\n", img_src); + } + + if (setup->warn_resize && image_size->is_hidpi) { + get_image_sizes (img_dst, &tmpw, &tmph, NULL, FALSE); + if (img_w != tmpw || img_h != tmph) + g_print (" Warning: generated image '%s' doesn't have required dimensions: need %lux%lu, got %lux%lu\n", img_dst, img_w, img_h, tmpw, tmph); } + } else { + log_error ("generate_image: image %s sizes are %lux%lu\n", img_src, src_img_w, src_img_h); } } - if (! image_size->is_thumbnail) { - modify_exif (img_dst, exif_data, setup->erase_exif_thumbnail, setup->strip_xmp); - } + } + if (! image_size->is_thumbnail) { + modify_exif (img_dst, exif_data, setup->erase_exif_thumbnail, setup->strip_xmp); + } - exif_data_free (exif_data); - g_free (img_src); - g_free (img_dst); + exif_data_free (exif_data); + g_free (img_src); + g_free (img_dst); + + return res; +} + +/* + * generate_image: generate needed image sizes + */ +gboolean +generate_image (TGallerySetup *setup, + TAlbum *items, + TIndexItem *item, + TPathInfo *path_info, + gboolean query_update) +{ + gboolean res; + GList *l; + TImageSize *image_size; + int i; + + res = ! query_update; + for (i = 0; i < 2; i++) { + /* process regular sizes first and then hidpi sizes in the second round */ + for (l = g_list_first (setup->design->image_sizes); l; l = g_list_next (l)) { + image_size = l->data; + if ((i == 0 && image_size->is_hidpi) || (i == 1 && ! image_size->is_hidpi)) + continue; + + res = (query_update && res) || generate_image_for_size (setup, items, item, path_info, image_size, query_update); + } } return res; } @@ -872,9 +936,9 @@ process_img_item (TGallerySetup *setup, struct HaveImageSizeData *img_size_data; GList *l; + album_protected = FALSE; if (list_mode) { /* Index stuff */ - album_protected = FALSE; if (items->type == GALLERY_TYPE_INDEX) { album_objects_count = 0; s1 = g_build_filename (path_info->src_dir, item->path, "index.xml", NULL); @@ -934,7 +998,7 @@ process_img_item (TGallerySetup *setup, tmp_image_size = l->data; if (! all_image_sizes && tmp_image_size != image_size) continue; - if (tmp_image_size->is_thumbnail) + if ((items->type == GALLERY_TYPE_ALBUM && tmp_image_size->is_thumbnail) || (items->type == GALLERY_TYPE_INDEX && ! tmp_image_size->is_thumbnail) || album_protected) continue; /* First calculate image paths */ if (all_image_sizes) { |
