summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2019-09-20 20:12:43 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2019-09-20 20:12:43 +0200
commitd3cbbd5b8ab09f3023bbe5067a39935495e59847 (patch)
tree1e7c858e60e030d3ae0a28450def05e345331251
parent004ba6b7e3546cf05f36b4fef7609d2ba4386fa5 (diff)
downloadcataract-d3cbbd5b8ab09f3023bbe5067a39935495e59847.tar.xz
generators: Force even base image dimensions for fractional HiDPI sizes
In case a dimension of the base image is not even and fractional HiDPI size is to be generated, the resulting image size computes to a non-integer values. Rounding in browsers may vary so let's stick with safe values and force even base image dimensions. This may result in slight crop applied before resize, generally imperceptible. Tested on Chromium 69 and Firefox 52.
-rw-r--r--src/generators.c28
-rw-r--r--src/jpeg-utils.c4
-rw-r--r--src/setup.c14
3 files changed, 34 insertions, 12 deletions
diff --git a/src/generators.c b/src/generators.c
index 5d5ba32..64ca08b 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -437,6 +437,19 @@ have_album_image_size_cb (gchar **args, gpointer user_data)
return FALSE;
}
+static gboolean
+have_fractional_hidpi_size (TGallerySetup *setup)
+{
+ int i;
+ double iptr;
+
+ if (setup->design->hidpi_sizes)
+ for (i = 0; setup->design->hidpi_sizes[i] != 0; i++)
+ if (modf (setup->design->hidpi_sizes[i], &iptr) != 0.0)
+ return TRUE;
+ return FALSE;
+}
+
static gboolean
generate_image_for_size (TGallerySetup *setup,
@@ -457,6 +470,7 @@ generate_image_for_size (TGallerySetup *setup,
int src_img_quality, img_quality;
ExifData *exif_data;
int shave_amount;
+ gboolean hidpi_strict_dimensions;
res = ! query_update;
@@ -476,6 +490,7 @@ generate_image_for_size (TGallerySetup *setup,
exif_data = exif_data_new_empty ();
metadata_apply_overrides (exif_data, setup, path_info, items, item, image_size);
+ hidpi_strict_dimensions = image_size->is_hidpi;
/* Do something when required */
res = res || needs_update (img_src, img_dst);
@@ -515,8 +530,8 @@ generate_image_for_size (TGallerySetup *setup,
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);
+ img_w = (gdouble) ref_img_w * image_size->hidpi_scale_factor;
+ img_h = (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);
@@ -568,6 +583,13 @@ generate_image_for_size (TGallerySetup *setup,
tmpw + image_size->no_resize_threshold, tmph + image_size->no_resize_threshold); */
} else {
calculate_sizes (tmpw, tmph, &img_w, &img_h);
+ /* For HiDPI sizes that are not integer the base image dimensions must be even */
+ if ((img_w % 2 != 0 || img_h % 2 != 0) && have_fractional_hidpi_size (setup)) {
+ img_w = img_w / 2 * 2;
+ img_h = img_h / 2 * 2;
+ /* This flag will take care of a convenient crop of the source image before resize based on the aspect ratio difference */
+ hidpi_strict_dimensions = TRUE;
+ }
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);
}
@@ -588,7 +610,7 @@ generate_image_for_size (TGallerySetup *setup,
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, image_size->is_hidpi, exif_data,
+ if (! resize_image (img_src, img_dst, img_w, img_h, img_quality, image_size->is_thumbnail, setup->autorotate, hidpi_strict_dimensions, 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);
}
diff --git a/src/jpeg-utils.c b/src/jpeg-utils.c
index aa3a1cc..e992bfa 100644
--- a/src/jpeg-utils.c
+++ b/src/jpeg-utils.c
@@ -549,9 +549,9 @@ resize_image (const gchar *src, const gchar *dst,
if (source_aspect != target_aspect) {
if (target_aspect >= source_aspect) {
new_w = w;
- new_h = lround ((double) w / target_aspect);
+ new_h = (double) w / target_aspect;
} else {
- new_w = lround ((double) h * target_aspect);
+ new_w = (double) h * target_aspect;
new_h = h;
}
MagickCropImage (magick_wand, new_w, new_h, (w - new_w) / 2, (h - new_h) / 2);
diff --git a/src/setup.c b/src/setup.c
index 266c36e..1ff7ae2 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -328,13 +328,13 @@ parse_design_setup_xml (const gchar *filename)
hidpi_image_size->no_resize_threshold = 0;
hidpi_image_size->availability_threshold = 0;
hidpi_image_size->name = g_strdup_printf (HIDPI_NAME_FORMAT, image_size->name, hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->landscape_width = lround ((gdouble) image_size->landscape_width * hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->landscape_height = lround ((gdouble) image_size->landscape_height * hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->portrait_width = lround ((gdouble) image_size->portrait_width * hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->portrait_height = lround ((gdouble) image_size->portrait_height * hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->square_size = lround ((gdouble) image_size->square_size * hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->crop_width = lround ((gdouble) image_size->crop_width * hidpi_image_size->hidpi_scale_factor);
- hidpi_image_size->crop_height = lround ((gdouble) image_size->crop_height * hidpi_image_size->hidpi_scale_factor);
+ hidpi_image_size->landscape_width = (gdouble) image_size->landscape_width * hidpi_image_size->hidpi_scale_factor;
+ hidpi_image_size->landscape_height = (gdouble) image_size->landscape_height * hidpi_image_size->hidpi_scale_factor;
+ hidpi_image_size->portrait_width = (gdouble) image_size->portrait_width * hidpi_image_size->hidpi_scale_factor;
+ hidpi_image_size->portrait_height = (gdouble) image_size->portrait_height * hidpi_image_size->hidpi_scale_factor;
+ hidpi_image_size->square_size = (gdouble) image_size->square_size * hidpi_image_size->hidpi_scale_factor;
+ hidpi_image_size->crop_width = (gdouble) image_size->crop_width * hidpi_image_size->hidpi_scale_factor;
+ hidpi_image_size->crop_height = (gdouble) image_size->crop_height * hidpi_image_size->hidpi_scale_factor;
if (! hidpi_image_size->is_thumbnail && design->hidpi_quality > 0)
hidpi_image_size->quality = design->hidpi_quality;
if (hidpi_image_size->is_thumbnail && design->hidpi_thumbnail_quality > 0)