diff options
| -rw-r--r-- | sample/src/CIAF_1/index.xml | 9 | ||||
| -rw-r--r-- | src/generators.c | 15 | ||||
| -rw-r--r-- | src/items.c | 49 | ||||
| -rw-r--r-- | src/items.h | 13 | ||||
| -rw-r--r-- | src/jpeg-utils.cpp | 25 | ||||
| -rw-r--r-- | src/jpeg-utils.h | 7 |
6 files changed, 100 insertions, 18 deletions
diff --git a/sample/src/CIAF_1/index.xml b/sample/src/CIAF_1/index.xml index 5d9ad5a..ed9e150 100644 --- a/sample/src/CIAF_1/index.xml +++ b/sample/src/CIAF_1/index.xml @@ -26,7 +26,10 @@ <author>John Doe Jr.</author> <description>CIAF - Czech International Air Fest 2007</description> <keywords>ciaf,aircraft,military,exhibition</keywords> - </meta> + </meta> + + <!-- global thumbnail crop hint for simple square mode --> + <thumbnail crop="top" /> </general> <items> @@ -38,12 +41,14 @@ <item src="img_6802.jpg" preview="preview/img_6802.jpg"> <title>Photo title</title> <title_description>This photo uses supplied preview image. Some people (me) can see the difference in sharpness.</title_description> + <thumbnail crop="center" /> </item> <item src="img_6802c.jpg" preview="preview/img_6802.jpg"> <nofullsize /> <title>Photo title</title> <title_description>This photo doesn't contain link to original image, but src parameter is specified.</title_description> + <thumbnail crop="bottom" /> </item> <separator><![CDATA[This is a separator inside a single album. We <span style="text-decoration: underline;">can</span> <small>have</small> <strong>CDATA</strong> entries here!]]></separator> @@ -114,6 +119,7 @@ <metadata> <external_exif src="exif/5l9a4978.exv" /> </metadata> + <thumbnail crop="left" /> </item> <item src="img_1453c.jpg"> @@ -132,6 +138,7 @@ <external_exif src="exif/5l9a4978.exv" /> <timezone shift="+02:15" /> </metadata> + <thumbnail crop="right" /> </item> </items> diff --git a/src/generators.c b/src/generators.c index 52ec1ac..2038424 100644 --- a/src/generators.c +++ b/src/generators.c @@ -170,6 +170,12 @@ metadata_apply_overrides (ExifData *exif_data, exif_data->external_exif_data = NULL; if (setup->write_supplied_exif && item->metadata_external_exif) exif_data->external_exif_data = g_build_filename (path_info->src_dir, item->metadata_external_exif, NULL); + + exif_data->squared_thumbnail_type = setup->squared_thumbnail_type; + + exif_data->thumbnail_crop_hint = item->thumbnail_crop_hint; + if (exif_data->thumbnail_crop_hint == CROP_HINT_UNDEFINED) + exif_data->thumbnail_crop_hint = items->thumbnail_crop_hint; } @@ -212,6 +218,9 @@ generate_image (TGallerySetup *setup, if (img_src == NULL || img_dst == NULL) continue; + exif_data = exif_data_new_empty (); + metadata_apply_overrides (exif_data, setup, path_info, items, item); + /* Do something when required */ res = res || needs_update (img_src, img_dst); if (! query_update) { @@ -251,7 +260,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, setup->autorotate)) + if (! resize_image (img_src, img_dst, img_w, img_h, quality, is_thumbnail, setup->autorotate, exif_data)) 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); @@ -259,12 +268,10 @@ generate_image (TGallerySetup *setup, } } if (! is_thumbnail) { - exif_data = exif_data_new_empty (); - metadata_apply_overrides (exif_data, setup, path_info, items, item); modify_exif (img_dst, exif_data, setup->erase_exif_thumbnail, setup->strip_xmp); - exif_data_free (exif_data); } + exif_data_free (exif_data); g_free (img_src); g_free (img_dst); } diff --git a/src/items.c b/src/items.c index 85f0a26..31ab41f 100644 --- a/src/items.c +++ b/src/items.c @@ -85,6 +85,29 @@ parse_datetime_string (const gchar *str) return rt; } +static TCropHint +parse_thumbnail_crop_hint (const gchar *str) +{ + g_return_val_if_fail (str != NULL, CROP_HINT_UNDEFINED); + + if (g_ascii_strcasecmp (str, "center") == 0) + return CROP_HINT_CENTER; + else + if (g_ascii_strcasecmp (str, "left") == 0) + return CROP_HINT_LEFT; + else + if (g_ascii_strcasecmp (str, "right") == 0) + return CROP_HINT_RIGHT; + else + if (g_ascii_strcasecmp (str, "top") == 0) + return CROP_HINT_TOP; + else + if (g_ascii_strcasecmp (str, "bottom") == 0) + return CROP_HINT_BOTTOM; + else + return CROP_HINT_UNDEFINED; +} + /* * parse_album_xml: XML parser for gallery index.xml files @@ -161,6 +184,12 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) g_free (s); } + s = xml_file_get_node_attribute (xml, "/gallery/general/thumbnail", "crop"); + if (s != NULL) { + index->thumbnail_crop_hint = parse_thumbnail_crop_hint (s); + g_free (s); + } + index->nofullsize = xml_file_get_node_present (xml, "/gallery/general/nofullsize"); index->fullsize = xml_file_get_node_present (xml, "/gallery/general/fullsize"); @@ -306,6 +335,14 @@ parse_album_xml (const gchar *filename, TPathInfo *path_info) g_free (s2); } + s = g_strdup_printf ("/gallery/items/*[%d]/thumbnail", i + 1); + s2 = xml_file_get_node_attribute (xml, s, "crop"); + g_free (s); + if (s2 != NULL) { + item->thumbnail_crop_hint = parse_thumbnail_crop_hint (s2); + g_free (s2); + } + if (item->path || item->preview) { g_ptr_array_add (index->items, item); } else { @@ -422,15 +459,15 @@ free_album_data (TAlbum *album) * get_album_info: retrieve number of items and protected status in the specified album */ void -get_album_info (const gchar *filename, int *objects_count, gboolean *protected) +get_album_info (const gchar *filename, int *objects_count, gboolean *is_protected) { TXMLFile *xml; int count, hidden; if (objects_count) *objects_count = 0; - if (protected) - *protected = FALSE; + if (is_protected) + *is_protected = FALSE; xml = xml_parser_load (filename); if (xml == NULL) @@ -441,9 +478,9 @@ get_album_info (const gchar *filename, int *objects_count, gboolean *protected) if (objects_count) *objects_count = count - hidden; - if (protected) - *protected = xml_file_get_node_present (xml, "/gallery/general/auth/username") && - xml_file_get_node_present (xml, "/gallery/general/auth/password"); + if (is_protected) + *is_protected = xml_file_get_node_present (xml, "/gallery/general/auth/username") && + xml_file_get_node_present (xml, "/gallery/general/auth/password"); xml_parser_free (xml); } diff --git a/src/items.h b/src/items.h index 331f29e..b502e71 100644 --- a/src/items.h +++ b/src/items.h @@ -39,6 +39,15 @@ typedef enum { AUTH_TYPE_BASIC } TAuthType; +typedef enum { + CROP_HINT_UNDEFINED = 0, + CROP_HINT_CENTER, + CROP_HINT_LEFT, + CROP_HINT_RIGHT, + CROP_HINT_TOP, + CROP_HINT_BOTTOM +} TCropHint; + typedef struct { TGalleryType type; gchar *ID; @@ -66,6 +75,7 @@ typedef struct { TAuthType auth_type; int metadata_tz_shift; /* minutes */ time_t metadata_fake_datetime; + TCropHint thumbnail_crop_hint; } TAlbum; typedef struct { @@ -85,6 +95,7 @@ typedef struct { gchar *metadata_external_exif; int metadata_tz_shift; /* minutes */ time_t metadata_fake_datetime; + TCropHint thumbnail_crop_hint; } TIndexItem; typedef struct { @@ -115,7 +126,7 @@ void free_album_data (TAlbum *index); /* * get_album_info: retrieve number of items and protected status in the specified album */ -void get_album_info (const gchar *filename, int *objects_count, gboolean *protected); +void get_album_info (const gchar *filename, int *objects_count, gboolean *is_protected); /* * get_album_titles: retrieve title, description and first thumbnail from specified album diff --git a/src/jpeg-utils.cpp b/src/jpeg-utils.cpp index d7382c8..be95ec9 100644 --- a/src/jpeg-utils.cpp +++ b/src/jpeg-utils.cpp @@ -432,8 +432,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, - gboolean autorotate) + gboolean autorotate, + ExifData *exif) { MagickWand *magick_wand; ExceptionType severity; @@ -460,13 +460,30 @@ resize_image (const gchar *src, const gchar *dst, { /* Process thumbnail if required */ if (thumbnail) { - switch (squared_thumbnail_type) { + switch (exif->squared_thumbnail_type) { case THUMBNAIL_SQUARE_TYPE_SIMPLE: w = MagickGetImageWidth (magick_wand); h = MagickGetImageHeight (magick_wand); amount = MAX (w, h) * SQUARED_SIMPLE_SHAVE_AMOUNT / 100; amount = MIN (w - 2*amount, h - 2*amount); - MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, (h - amount) / 2); + switch (exif->thumbnail_crop_hint) { + case CROP_HINT_UNDEFINED: + case CROP_HINT_CENTER: + MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, (h - amount) / 2); + break; + case CROP_HINT_LEFT: + MagickCropImage (magick_wand, amount, amount, 0, (h - amount) / 2); + break; + case CROP_HINT_RIGHT: + MagickCropImage (magick_wand, amount, amount, w - amount, (h - amount) / 2); + break; + case CROP_HINT_TOP: + MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, 0); + break; + case CROP_HINT_BOTTOM: + MagickCropImage (magick_wand, amount, amount, (w - amount) / 2, h - amount); + break; + } break; default: break; diff --git a/src/jpeg-utils.h b/src/jpeg-utils.h index 0e3cd1f..f8c9b6d 100644 --- a/src/jpeg-utils.h +++ b/src/jpeg-utils.h @@ -20,6 +20,7 @@ #include <glib.h> #include "setup.h" +#include "items.h" G_BEGIN_DECLS @@ -54,6 +55,8 @@ typedef struct { int timezone_shift; time_t fake_datetime; gchar *external_exif_data; + ThumbnailSquareType squared_thumbnail_type; + TCropHint thumbnail_crop_hint; } ExifData; @@ -87,8 +90,8 @@ 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, - gboolean autorotate); + gboolean autorotate, + ExifData *exif); /* * get_image_sizes: retrieve image dimensions |
