diff options
| -rw-r--r-- | sample/src/setup.xml | 4 | ||||
| -rw-r--r-- | src/generators.c | 10 | ||||
| -rw-r--r-- | src/jpeg-utils.cpp | 80 | ||||
| -rw-r--r-- | src/jpeg-utils.h | 6 | ||||
| -rw-r--r-- | src/setup.c | 1 | ||||
| -rw-r--r-- | src/setup.h | 1 |
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; |
