summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sample/src/setup.xml4
-rw-r--r--src/generators.c10
-rw-r--r--src/jpeg-utils.cpp80
-rw-r--r--src/jpeg-utils.h6
-rw-r--r--src/setup.c1
-rw-r--r--src/setup.h1
6 files changed, 92 insertions, 10 deletions
diff --git a/sample/src/setup.xml b/sample/src/setup.xml
index d042630..7fde549 100644
--- a/sample/src/setup.xml
+++ b/sample/src/setup.xml
@@ -36,6 +36,10 @@
<!-- simple - crop from center, shave 5% from borders -->
<!-- ... more to come! (looking for a fast and clever algorithm) -->
<squared_thumbnails type="none" />
+
+ <!-- autorotate input images according to EXIF information, unless -->
+ <!-- provided in the album source file (copy mode) (default = yes) -->
+ <autorotate value="yes" />
</images>
<meta>
diff --git a/src/generators.c b/src/generators.c
index b1c7b44..d7d180b 100644
--- a/src/generators.c
+++ b/src/generators.c
@@ -167,7 +167,7 @@ generate_image (TGallerySetup *setup,
}
/* Resize image */
else {
- get_image_sizes (img_src, &img_w, &img_h);
+ get_image_sizes (img_src, &img_w, &img_h, setup->autorotate);
if (img_w > 0 && img_h > 0) {
stats_images_inc ();
@@ -196,7 +196,7 @@ generate_image (TGallerySetup *setup,
quality = item->quality;
/* Perform resize and strip */
- if (! resize_image (img_src, img_dst, img_w, img_h, quality, is_thumbnail, setup->squared_thumbnail_type))
+ if (! resize_image (img_src, img_dst, img_w, img_h, quality, is_thumbnail, setup->squared_thumbnail_type, setup->autorotate))
log_error ("generate_image: error resizing image %s\n", img_src);
} else {
log_error ("generate_image: image %s sizes are %lux%lu\n", img_src, img_w, img_h);
@@ -466,7 +466,7 @@ write_html_album (TGallerySetup *setup,
img_thumb_w = img_thumb_h = 0;
get_image_paths (setup, items, item, i, path_info, thumb_image_size, NULL, &s2, &s3);
if (s2 != NULL)
- get_image_sizes (s2, &img_thumb_w, &img_thumb_h);
+ get_image_sizes (s2, &img_thumb_w, &img_thumb_h, setup->autorotate);
if (setup->squared_thumbnail_type != THUMBNAIL_SQUARE_TYPE_NONE || img_thumb_w == img_thumb_h)
s1 = "IMG_LIST_SQUARED";
@@ -681,10 +681,10 @@ write_html_image (TGallerySetup *setup,
}
/* Retrieve image sizes of preview and original image */
- get_image_sizes (img_dst, &img_w, &img_h);
+ get_image_sizes (img_dst, &img_w, &img_h, setup->autorotate);
image_fullsize = ! theme_size_is_original && img_orig_dst != NULL && ! IS_NOFULLSIZE (item, parent_items, setup);
if (image_fullsize) {
- get_image_sizes (img_orig_dst, &img_orig_w, &img_orig_h);
+ get_image_sizes (img_orig_dst, &img_orig_w, &img_orig_h, setup->autorotate);
g_hash_table_replace (defines, g_strdup ("HAS_FULLSIZE"), g_strdup (""));
}
diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp
index 55e3442..663e97a 100644
--- a/src/jpeg-utils.cpp
+++ b/src/jpeg-utils.cpp
@@ -225,6 +225,66 @@ free_exif_data (TExifData *data)
}
+static void
+autorotate_image (MagickWand *magick_wand)
+{
+ MagickBooleanType b;
+ PixelWand *pixel_wand;
+ ExceptionType severity;
+ gchar *description;
+
+ pixel_wand = NewPixelWand ();
+ b = PixelSetColor (pixel_wand, "#000000");
+ if (b == MagickFalse) {
+ description = MagickGetException (magick_wand, &severity);
+ log_error ("autorotate_image: Error creating pixel wand: %s %s %ld %s\n", GetMagickModule(), description);
+ MagickRelinquishMemory (description);
+ }
+
+ b = MagickTrue;
+ switch (MagickGetImageOrientation (magick_wand))
+ {
+ case TopRightOrientation:
+ b = MagickFlopImage (magick_wand);
+ break;
+ case BottomRightOrientation:
+ b = MagickRotateImage (magick_wand, pixel_wand, 180.0);
+ break;
+ case BottomLeftOrientation:
+ b = MagickFlipImage (magick_wand);
+ break;
+ case LeftTopOrientation:
+ b = MagickTransposeImage (magick_wand);
+ break;
+ case RightTopOrientation:
+ b = MagickRotateImage (magick_wand, pixel_wand, 90.0);
+ break;
+ case RightBottomOrientation:
+ b = MagickTransverseImage (magick_wand);
+ break;
+ case LeftBottomOrientation:
+ b = MagickRotateImage (magick_wand, pixel_wand, 270.0);
+ break;
+ default:
+ break;
+ }
+
+ if (b == MagickFalse) {
+ description = MagickGetException (magick_wand, &severity);
+ log_error ("autorotate_image: Error rotating image: %s %s %ld %s\n", GetMagickModule(), description);
+ MagickRelinquishMemory (description);
+ }
+
+ b = MagickSetImageOrientation (magick_wand, TopLeftOrientation);
+ if (b == MagickFalse) {
+ description = MagickGetException (magick_wand, &severity);
+ log_error ("autorotate_image: Error saving orientation: %s %s %ld %s\n", GetMagickModule(), description);
+ MagickRelinquishMemory (description);
+ }
+
+ DestroyPixelWand (pixel_wand);
+}
+
/*
* resize_image: resize image pointed by src and save result to dst
*/
@@ -233,7 +293,8 @@ resize_image (const gchar *src, const gchar *dst,
unsigned long size_x, unsigned long size_y,
int quality,
gboolean thumbnail,
- ThumbnailSquareType squared_thumbnail_type)
+ ThumbnailSquareType squared_thumbnail_type,
+ gboolean autorotate)
{
MagickWand *magick_wand;
ExceptionType severity;
@@ -251,6 +312,9 @@ resize_image (const gchar *src, const gchar *dst,
return FALSE;
}
+ if (autorotate)
+ autorotate_image (magick_wand);
+
/* Don't resize if smaller than desired size */
if (MagickGetImageWidth (magick_wand) > size_x ||
MagickGetImageHeight (magick_wand) > size_y)
@@ -295,9 +359,11 @@ resize_image (const gchar *src, const gchar *dst,
*/
void
get_image_sizes (const gchar *img,
- unsigned long *width, unsigned long *height)
+ unsigned long *width, unsigned long *height,
+ gboolean autorotate)
{
MagickWand *magick_wand;
+ MagickBooleanType b;
ExceptionType severity;
gchar *description;
@@ -306,12 +372,20 @@ get_image_sizes (const gchar *img,
/* Read an image. */
magick_wand = NewMagickWand();
- if (MagickPingImage (magick_wand, img) == MagickFalse) {
+ if (autorotate)
+ b = MagickReadImage (magick_wand, img);
+ else
+ b = MagickPingImage (magick_wand, img);
+ if (b == MagickFalse) {
description = MagickGetException (magick_wand, &severity);
log_error ("Error reading image info: %s %s %ld %s\n", GetMagickModule(), description);
MagickRelinquishMemory(description);
return;
}
+
+ if (autorotate)
+ autorotate_image (magick_wand);
+
*width = MagickGetImageWidth (magick_wand);
*height = MagickGetImageHeight (magick_wand);
diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h
index e5845bc..a682fd1 100644
--- a/src/jpeg-utils.h
+++ b/src/jpeg-utils.h
@@ -73,13 +73,15 @@ gboolean resize_image (const gchar *src, const gchar *dst,
unsigned long size_x, unsigned long size_y,
int quality,
gboolean thumbnail,
- ThumbnailSquareType squared_thumbnail_type);
+ ThumbnailSquareType squared_thumbnail_type,
+ gboolean autorotate);
/*
* get_image_sizes: retrieve image dimensions
*/
void get_image_sizes (const gchar *img,
- unsigned long *width, unsigned long *height);
+ unsigned long *width, unsigned long *height,
+ gboolean autorotate);
/*
* calculate_sizes: calculate maximal image sizes within specified limits keeping aspect ratio
diff --git a/src/setup.c b/src/setup.c
index e88a292..f053555 100644
--- a/src/setup.c
+++ b/src/setup.c
@@ -95,6 +95,7 @@ parse_setup_xml (const gchar *filename)
setup->use_iptc_exif = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/use_iptc_exif", "value", FALSE);
setup->erase_exif_thumbnail = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/erase_embed_thumbnail", "value", FALSE);
setup->nofullsize = xml_file_get_node_present (xml, "/gallery_setup/images/nofullsize");
+ setup->autorotate = xml_file_get_node_attribute_boolean (xml, "/gallery_setup/images/autorotate", "value", TRUE);
s = xml_file_get_node_attribute (xml, "/gallery_setup/images/squared_thumbnails", "type");
if (s && g_ascii_strcasecmp (s, "simple") == 0)
diff --git a/src/setup.h b/src/setup.h
index 56f7e84..7e4ce1e 100644
--- a/src/setup.h
+++ b/src/setup.h
@@ -58,6 +58,7 @@ typedef struct {
gboolean erase_exif_thumbnail;
gboolean nofullsize;
ThumbnailSquareType squared_thumbnail_type;
+ gboolean autorotate;
/* meta section */
gchar *meta_author;