summaryrefslogtreecommitdiff
path: root/src/jpeg-utils.cpp
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2016-10-02 16:58:27 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2016-10-02 17:32:43 +0200
commitddd9556689af055355a07cf2766fe95eaed4e38e (patch)
treeb6de3e57a5cfbd0d855277c3b8c93f16549f0bf2 /src/jpeg-utils.cpp
parent56ff7bc45505b3e39b2f9be70e7bee3f80ec4f70 (diff)
downloadcataract-ddd9556689af055355a07cf2766fe95eaed4e38e.tar.xz
Add support for HiDPI images
This works by creating corresponding hidpi image sizes on startup and letting the machinery generate high resolution images from the source images (no way to use supplied images). However since browsers expect exact image dimension multiples for the particular scale factor, a reference image size (scale factor 1.0x) must be read first, then cropped to match reference aspect ratio and resized to exact dimensions. That way pixel-perfect results can be achieved for the chosen scale factor. TODO: the CSS background-image: image-set() tags are not supported on Firefox. TODO: try the 1.5x scale factor
Diffstat (limited to 'src/jpeg-utils.cpp')
-rw-r--r--src/jpeg-utils.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index aaf59fc..d7134c2 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -507,6 +507,7 @@ resize_image (const gchar *src, const gchar *dst,
int quality,
gboolean thumbnail,
gboolean autorotate,
+ gboolean hidpi_strict_dimensions,
ExifData *exif,
gchar *resize_opts)
{
@@ -539,7 +540,7 @@ resize_image (const gchar *src, const gchar *dst,
autorotate_image (magick_wand);
/* Don't resize if smaller than desired size */
- if (MagickGetImageWidth (magick_wand) > size_x || MagickGetImageHeight (magick_wand) > size_y)
+ if (hidpi_strict_dimensions || MagickGetImageWidth (magick_wand) > size_x || MagickGetImageHeight (magick_wand) > size_y)
{
/* Prepare image before resizing */
if (thumbnail) {
@@ -587,8 +588,29 @@ resize_image (const gchar *src, const gchar *dst,
}
}
+ /* Shave the source image to match exact dimensions after resize */
+ if (hidpi_strict_dimensions && (! thumbnail || exif->thumbnail_crop_style == CROP_STYLE_NORMAL)) {
+ w = MagickGetImageWidth (magick_wand);
+ h = MagickGetImageHeight (magick_wand);
+ source_aspect = (double) w / (double) h;
+ target_aspect = (double) size_x / (double) size_y;
+ if (source_aspect != target_aspect) {
+ if (target_aspect >= source_aspect) {
+ new_w = w;
+ new_h = lround ((double) w / target_aspect);
+ } else {
+ new_w = lround ((double) h * target_aspect);
+ new_h = h;
+ }
+ MagickCropImage (magick_wand, new_w, new_h, (w - new_w) / 2, (h - new_h) / 2);
+ g_warn_if_fail (MagickGetImageWidth (magick_wand) == new_w);
+ g_warn_if_fail (MagickGetImageHeight (magick_wand) == new_h);
+ }
+ }
+
if (resize_opts == NULL) {
/* Perform internal resizing */
+ /* Note: MagickResizeImage() does no aspect correction, stretching the image to the required dimensions */
if (thumbnail) {
MagickThumbnailImage (magick_wand, size_x, size_y);
} else {
@@ -682,8 +704,8 @@ get_image_sizes (const gchar *img,
ExceptionType severity;
gchar *description;
- *width = -1;
- *height = -1;
+ *width = 0;
+ *height = 0;
if (quality)
*quality = -1;