summaryrefslogtreecommitdiff
path: root/src/generators.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/generators.c')
-rw-r--r--src/generators.c194
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) {