summaryrefslogtreecommitdiff
path: root/generators.c
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-07-27 19:13:28 +0200
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-07-27 19:13:28 +0200
commit510fff156db65795cbf211e7910a67fb316cb404 (patch)
treedfbec486ffeab2d6886f9f51863f723a2d5cd574 /generators.c
downloadcataract-510fff156db65795cbf211e7910a67fb316cb404.tar.xz
Initial commitv0.99.0
Diffstat (limited to 'generators.c')
-rw-r--r--generators.c882
1 files changed, 882 insertions, 0 deletions
diff --git a/generators.c b/generators.c
new file mode 100644
index 0000000..a3abe24
--- /dev/null
+++ b/generators.c
@@ -0,0 +1,882 @@
+/* Cataract - Static web photo gallery generator
+ * Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "config.h"
+#include "setup.h"
+#include "items.h"
+#include "jpeg-utils.h"
+#include "gallery-utils.h"
+
+
+/*
+ * generate_image: auxiliary function for write_html_album
+ */
+void
+generate_image (TGallerySetup *setup,
+ TAlbum *items,
+ TIndexItem *item,
+ const char *dst,
+ unsigned long *img_w, unsigned long *img_h,
+ const char **img_src)
+{
+ unsigned long new_w, new_h;
+ char *thumb_dst;
+ char *big_dst;
+ char *big_src;
+ char *orig_dst;
+ char *img_src_full;
+ char *s1, *s2;
+ int bigq;
+
+
+ *img_src = item->thumbnail;
+ if (items->type == GALLERY_TYPE_INDEX)
+ *img_src = item->thumbnail;
+ else
+ if (items->type == GALLERY_TYPE_ALBUM)
+ *img_src = item->path;
+
+ img_src_full = g_strconcat (items->base_dir, "/", *img_src, NULL);
+ get_image_sizes (img_src_full, img_w, img_h);
+
+ if ((img_w > 0) && (img_h > 0)) {
+ new_w = *img_w;
+ new_h = *img_h;
+
+
+ /* Generate thumbnail */
+ s1 = g_path_get_dirname (dst);
+ s2 = g_path_get_basename (*img_src);
+ thumb_dst = g_strconcat (s1, "/", THUMBNAIL_DIR, "/", s2, NULL);
+ g_free (s1);
+ g_free (s2);
+ if (setup->verbose) printf (" Generating thumbnail of '%s' ...", *img_src);
+
+ if ((*img_w / *img_h) >= 1)
+ calculate_sizes (setup->thumbnail_landscape_width, setup->thumbnail_landscape_height, &new_w, &new_h);
+ else
+ calculate_sizes (setup->thumbnail_portrait_width, setup->thumbnail_portrait_height, &new_w, &new_h);
+ if (! resize_image (img_src_full, thumb_dst, new_w, new_h, setup->thumbnail_quality))
+ fprintf (stderr, "write_html_index: error resizing thumbnail %s\n", img_src_full);
+ else
+ if (setup->verbose) printf (" done.\n");
+ g_free (thumb_dst);
+
+
+ /* Generate/copy preview and original image */
+ if (items->type == GALLERY_TYPE_ALBUM)
+ {
+ s1 = g_path_get_dirname (dst);
+ big_dst = g_strconcat (s1, "/", IMG_BIG_DIR, "/", *img_src, NULL);
+ g_free (s1);
+
+ if (item->preview == NULL) {
+ /* No preview image supplied, generate it from original */
+ bigq = setup->preview_quality;
+ if ((items->quality > 0) && (items->quality <= 100))
+ bigq = items->quality;
+ if ((item->quality > 0) && (item->quality <= 100))
+ bigq = item->quality;
+ new_w = *img_w;
+ new_h = *img_h;
+
+ if (setup->verbose) printf (" Generating preview of '%s' ...", *img_src);
+ if ((item->width > 0) && (item->height > 0)) {
+ calculate_sizes (item->width, item->height, &new_w, &new_h);
+ } else {
+ if ((*img_w / *img_h) >= 1)
+ {
+ if ((items->landscape_width > 0) && (items->landscape_height > 0))
+ calculate_sizes (items->landscape_width, items->landscape_height, &new_w, &new_h);
+ else
+ calculate_sizes (setup->preview_landscape_width, setup->preview_landscape_height, &new_w, &new_h);
+ }
+ else
+ {
+ if ((items->portrait_width > 0) && (items->portrait_height > 0))
+ calculate_sizes (items->portrait_width, items->portrait_height, &new_w, &new_h);
+ else
+ calculate_sizes (setup->preview_portrait_width, setup->preview_portrait_height, &new_w, &new_h);
+ }
+ }
+
+ if (! resize_image (img_src_full, big_dst, new_w, new_h, bigq))
+ fprintf (stderr, "write_html_index: error resizing big image %s\n", img_src_full);
+ else
+ if (setup->verbose) printf (" done.\n");
+ }
+ else
+ {
+ /* Copy the preview (big) image provided */
+ big_src = g_strconcat (items->base_dir, "/", item->preview, NULL);
+ if (setup->verbose) printf (" Copying preview image '%s' ...", *img_src);
+ if (! copy_file (big_src, big_dst))
+ fprintf (stderr, "write_html_index: error copying preview image %s\n", big_src);
+ else
+ if (setup->verbose) printf (" done.\n");
+ g_free (big_src);
+ }
+ g_free (big_dst);
+
+ if (! item->nofullsize)
+ {
+ s1 = g_path_get_dirname(dst);
+ orig_dst = g_strconcat (s1, "/", IMG_ORIG_DIR, "/", *img_src, NULL);
+ g_free (s1);
+ if (setup->verbose) printf (" Copying original image '%s' ...", *img_src);
+ if (! copy_file(img_src_full, orig_dst))
+ fprintf (stderr, "write_html_index: error copying original image %s\n", img_src_full);
+ else
+ if (setup->verbose) printf(" done.\n");
+ g_free (orig_dst);
+ }
+ }
+ }
+ g_free (img_src_full);
+}
+
+
+
+/*
+ * write_html_album: process album and index template files
+ *
+ * template_src = template file of the album/index
+ * dst = save generated file as
+ * items = array of items in the album/index
+ *
+ */
+gboolean
+write_html_album (TGallerySetup *setup,
+ const char *template_src,
+ const char *dst,
+ TAlbum *items)
+{
+ #define BUFFER_SIZE 65536
+ FILE *fin;
+ FILE *fout;
+ char *buffer;
+ char *buf_img_list_landscape;
+ char *buf_img_list_portrait;
+ char *buf_go_up_string;
+ gboolean in_img_list;
+ gboolean in_img_list_landscape;
+ gboolean in_img_list_portrait;
+ gboolean in_go_up_string;
+ char *b;
+ char *s1, *s2, *s3;
+ TAlbum *parent;
+ TIndexItem *item;
+ int level;
+ gboolean res;
+ int i;
+ unsigned long img_w, img_h;
+ const char *img_src;
+
+
+ fin = fopen (template_src, "r");
+ if (fin == NULL) {
+ fprintf (stderr, "write_html_index: error reading file \"%s\": %s\n", template_src, strerror (errno));
+ return FALSE;
+ }
+ fout = fopen (dst, "w");
+ if (fout == NULL) {
+ fprintf (stderr, "write_html_index: error writing to file \"%s\": %s\n", dst, strerror (errno));
+ fclose (fin);
+ return FALSE;
+ }
+
+ buffer = malloc (BUFFER_SIZE);
+ buf_img_list_landscape = malloc (BUFFER_SIZE);
+ buf_img_list_portrait = malloc (BUFFER_SIZE);
+ buf_go_up_string = malloc (BUFFER_SIZE);
+ in_img_list = FALSE;
+ in_img_list_landscape = FALSE;
+ in_img_list_portrait = FALSE;
+ in_go_up_string = FALSE;
+ res = TRUE;
+
+ /* Read through the template and replace placeholders with real data */
+ while (! feof (fin))
+ {
+ memset (buffer, 0, BUFFER_SIZE);
+ if (! fgets (buffer, BUFFER_SIZE, fin))
+ break;
+ if (buffer == NULL)
+ continue;
+ b = strdup (buffer);
+
+
+ /* Block placeholders */
+ if (in_img_list && (strstr (buffer, "<!-- $(BEGIN_IMG_LIST_LANDSCAPE) -->"))) {
+ in_img_list_landscape = TRUE;
+ free (b);
+ continue;
+ }
+ if (in_img_list && (strstr (buffer, "<!-- $(END_IMG_LIST_LANDSCAPE) -->"))) {
+ in_img_list_landscape = FALSE;
+ free (b);
+ continue;
+ }
+ if (in_img_list && (strstr (buffer, "<!-- $(BEGIN_IMG_LIST_PORTRAIT) -->"))) {
+ in_img_list_portrait = TRUE;
+ free (b);
+ continue;
+ }
+ if (in_img_list && (strstr (buffer, "<!-- $(END_IMG_LIST_PORTRAIT) -->"))) {
+ in_img_list_portrait = FALSE;
+ free (b);
+ continue;
+ }
+ if (in_img_list && in_img_list_landscape) {
+ buf_img_list_landscape = strncat (buf_img_list_landscape, b, BUFFER_SIZE - strlen (buf_img_list_landscape) - 2);
+ free (b);
+ continue;
+ }
+ if (in_img_list && in_img_list_portrait) {
+ buf_img_list_portrait = strncat (buf_img_list_portrait, b, BUFFER_SIZE - strlen (buf_img_list_portrait) - 2);
+ free (b);
+ continue;
+ }
+
+ if (strstr (buffer, "<!-- $(BEGIN_GO_UP) -->")) {
+ memset (buf_go_up_string, 0, BUFFER_SIZE);
+ in_go_up_string = TRUE;
+ free (b);
+ continue;
+ }
+ if (in_go_up_string && (strstr (buffer, "<!-- $(END_GO_UP) -->"))) {
+ in_go_up_string = FALSE;
+ free (b);
+ /* print the "Go Up" string if not toplevel */
+ if (items->parent_index)
+ b = strdup (buf_go_up_string);
+ else continue;
+ }
+ if (in_go_up_string) {
+ buf_go_up_string = strncat (buf_go_up_string, b, BUFFER_SIZE - strlen (buf_go_up_string) - 2);
+ free (b);
+ continue;
+ }
+
+
+ /* Simple placeholders */
+ if (strstr (b, "<!-- $(ID) -->") && items->ID)
+ str_replace (&b, "<!-- $(ID) -->", items->ID);
+ if (strstr (b, "<!-- $(TITLE) -->") && items->title)
+ str_replace (&b, "<!-- $(TITLE) -->", items->title);
+ if (strstr (b, "<!-- $(DESCRIPTION) -->") && items->desc)
+ str_replace (&b, "<!-- $(DESCRIPTION) -->", items->desc);
+ if (strstr (b, "<!-- $(FOOTER) -->") && setup->footer)
+ str_replace (&b, "<!-- $(FOOTER) -->", setup->footer);
+ if (strstr (b, "<!-- $(TOTAL_ITEMS) -->")) {
+ s1 = g_strdup_printf ("%d", items->items->len);
+ str_replace (&b, "<!-- $(TOTAL_ITEMS) -->", s1);
+ g_free (s1);
+ }
+ if (strstr (b, "<!-- $(NAV_BAR) -->")) {
+ s1 = g_strdup (items->ID);
+ parent = items->parent_index;
+ level = 1;
+ while (parent) {
+ s3 = make_string ("../", level);
+ s2 = g_strconcat ("<a href=\"", s3, "index.html\">", parent->ID, "</a> &gt; ", s1, NULL);
+ free (s3);
+ g_free (s1);
+ s1 = s2;
+ parent = parent->parent_index;
+ level++;
+ }
+ str_replace (&b, "<!-- $(NAV_BAR) -->", s1);
+ g_free (s1);
+ }
+
+ /* Image list, nested placeholders */
+ if (strstr (buffer, "<!-- $(BEGIN_IMG_LIST) -->")) {
+ memset (buf_img_list_landscape, 0, BUFFER_SIZE);
+ memset (buf_img_list_portrait, 0, BUFFER_SIZE);
+ in_img_list = TRUE;
+ in_img_list_landscape = FALSE;
+ in_img_list_portrait = FALSE;
+ free (b);
+ continue;
+ }
+
+ if (in_img_list && (strstr (buffer, "<!-- $(END_IMG_LIST) -->"))) {
+ in_img_list = FALSE;
+ in_img_list_landscape = FALSE;
+ in_img_list_portrait = FALSE;
+
+ /* Now we have all block placeholders read, generate the items: */
+ for (i = 0; i < items->items->len; i++)
+ {
+ item = g_ptr_array_index (items->items, i);
+ if (item == NULL) {
+ fprintf (stderr, "write_html_index: error getting item %d\n", i);
+ free (b);
+ continue;
+ }
+
+ /* Generate the images (preview, original, thumbnail) */
+ img_w = 0;
+ img_h = 0;
+ img_src = NULL;
+ generate_image (setup, items, item, dst, &img_w, &img_h, &img_src);
+
+ /* Process HTML box code */
+ if ((img_w / img_h) >= 1)
+ s1 = strdup (buf_img_list_landscape);
+ else
+ s1 = strdup (buf_img_list_portrait);
+
+ while (strstr (s1, "<!-- $(ALBUM_SUBPATH) -->")) {
+ s2 = g_strconcat (item->path, "/index.html", NULL);
+ str_replace (&s1, "<!-- $(ALBUM_SUBPATH) -->", s2);
+ g_free (s2);
+ }
+ while (strstr (s1, "<!-- $(IMG_SUBPAGE) -->")) {
+ s2 = g_strconcat (img_src, ".html", NULL);
+ str_replace (&s1, "<!-- $(IMG_SUBPAGE) -->", s2);
+ g_free (s2);
+ }
+ while (strstr (s1, "<!-- $(IMG_TITLE) -->") && item->title)
+ str_replace (&s1, "<!-- $(IMG_TITLE) -->", item->title);
+ while (strstr (s1, "<!-- $(IMG_DESCRIPTION) -->") && item->title_description)
+ str_replace (&s1, "<!-- $(IMG_DESCRIPTION) -->", item->title_description);
+ while (strstr(s1, "<!-- $(ALBUM_NUM_ITEMS) -->")) {
+ s3 = g_strconcat (items->base_dir, "/", item->path, "/index.xml", NULL);
+ s2 = g_strdup_printf ("%d", get_album_objects_count(s3));
+ str_replace (&s1, "<!-- $(ALBUM_NUM_ITEMS) -->", s2);
+ g_free (s2);
+ g_free (s3);
+ }
+ while (strstr (s1, "<!-- $(IMG_THUMBNAIL) -->")) {
+ s3 = g_path_get_basename (img_src);
+ s2 = g_strconcat (THUMBNAIL_DIR, "/", s3, NULL);
+ str_replace (&s1, "<!-- $(IMG_THUMBNAIL) -->", s2);
+ g_free (s2);
+ g_free (s3);
+ }
+ while (strstr (s1, "<!-- $(IMG_FILENAME) -->"))
+ str_replace (&s1, "<!-- $(IMG_FILENAME) -->", img_src);
+
+
+ #ifdef __DEBUG_ALL__
+ printf("***** %s ******\n", s1);
+ #endif
+ if (! fputs (s1, fout)) {
+ fprintf (stderr, "write_html_index: error writing to file \"%s\": %s\n", dst, strerror (errno));
+ res = FALSE;
+ free (s1);
+ break;
+ }
+ free (s1);
+ }
+ free (b);
+ continue; /* no need to write anything */
+ }
+
+ /* Write the generated string to target file */
+ if (! fputs (b, fout)) {
+ fprintf (stderr, "write_html_index: error writing to file \"%s\": %s\n", dst, strerror (errno));
+ res = FALSE;
+ free (b);
+ break;
+ }
+ free (b);
+ }
+
+ fclose (fout);
+ fclose (fin);
+
+ free (buffer);
+ free (buf_img_list_landscape);
+ free (buf_img_list_portrait);
+ free (buf_go_up_string);
+ return res;
+}
+
+
+/*
+ * write_html_image: process single image template file
+ *
+ * template_src = template file of the album/index
+ * original_img = source image file (original full-size) to get EXIF data from
+ * dst = save generated file as
+ * item = data for the current item
+ * parent_items = array of items in the album, to determine our position and make links to previous/next image
+ *
+ */
+gboolean
+write_html_image (TGallerySetup *setup,
+ const char *template_src,
+ const char *original_img,
+ const char *dst,
+ TIndexItem *item,
+ TAlbum *parent_items)
+{
+ #define BUFFER_SIZE 65536
+ FILE *fin;
+ FILE *fout;
+ char *buffer;
+ char *big_dst;
+ char *orig_dst;
+ char *buf_img_fullsize_link;
+ gboolean in_img_fullsize_link;
+ TExifData *exif;
+ unsigned long img_big_w, img_big_h, img_orig_w, img_orig_h;
+ unsigned int item_index;
+ TIndexItem *previous_item;
+ TIndexItem *next_item;
+ TAlbum *parent;
+ int i;
+ char *s1, *s2, *s3;
+ char *b;
+ gboolean res;
+ int level;
+
+
+ fin = fopen (template_src, "r");
+ if (fin == NULL) {
+ fprintf (stderr, "write_html_image: error reading file \"%s\": %s\n", template_src, strerror (errno));
+ return FALSE;
+ }
+ fout = fopen (dst, "w");
+ if (fout == NULL) {
+ fprintf (stderr, "write_html_image: error writing to file \"%s\": %s\n", dst, strerror (errno));
+ fclose (fin);
+ return FALSE;
+ }
+
+ buffer = malloc (BUFFER_SIZE);
+ s1 = g_path_get_dirname (dst);
+ big_dst = g_strconcat (s1, "/", IMG_BIG_DIR, "/", item->path, NULL);
+ orig_dst = g_strconcat (s1, "/", IMG_ORIG_DIR, "/", item->path, NULL);
+ g_free (s1);
+ buf_img_fullsize_link = malloc (BUFFER_SIZE);
+ memset (buf_img_fullsize_link, 0, BUFFER_SIZE);
+ in_img_fullsize_link = FALSE;
+ res = TRUE;
+
+
+ /* Get EXIF data from the original image */
+ exif = malloc (sizeof (TExifData));
+ if (get_exif (original_img, exif))
+ fprintf (stderr, "write_html_image: error getting exif data from file \"%s\"\n", orig_dst);
+
+ /* Retrieve image sizes of preview and original image */
+ get_image_sizes (big_dst, &img_big_w, &img_big_h);
+ if (! item->nofullsize)
+ get_image_sizes (orig_dst, &img_orig_w, &img_orig_h);
+
+ /* Get our index in the album */
+ item_index = 0;
+ for (i = 0; i < parent_items->items->len; i++)
+ if (g_ptr_array_index (parent_items->items, i) == item) {
+ item_index = i + 1;
+ break;
+ }
+
+ /* Get previous and next items */
+ previous_item = NULL;
+ next_item = NULL;
+ if (item_index > 1)
+ previous_item = g_ptr_array_index (parent_items->items, item_index - 2);
+ if (item_index < parent_items->items->len)
+ next_item = g_ptr_array_index (parent_items->items, item_index);
+
+
+ /* Read through the template and replace placeholders with real data */
+ while (! feof (fin)) {
+ memset (buffer, 0, BUFFER_SIZE);
+ if (! fgets (buffer, BUFFER_SIZE, fin))
+ break;
+ b = strdup (buffer);
+
+
+ /* Block placeholders */
+ if (strstr (buffer, "<!-- $(BEGIN_IMG_FULLSIZE_LINK) -->")) {
+ in_img_fullsize_link = TRUE;
+ free (b);
+ continue;
+ }
+ if (strstr (buffer, "<!-- $(END_IMG_FULLSIZE_LINK) -->")) {
+ in_img_fullsize_link = FALSE;
+ free (b);
+ if (! item->nofullsize)
+ b = strdup (buf_img_fullsize_link);
+ else continue;
+ }
+ if (in_img_fullsize_link) {
+ buf_img_fullsize_link = strncat (buf_img_fullsize_link, b, BUFFER_SIZE - strlen (buf_img_fullsize_link) - 2);
+ free (b);
+ continue;
+ }
+
+
+ /* Simple placeholders */
+ if (strstr (b, "<!-- $(FILE_NAME) -->"))
+ str_replace (&b, "<!-- $(FILE_NAME) -->", item->path);
+ if (strstr (b, "<!-- $(TITLE) -->") && item->title)
+ str_replace (&b, "<!-- $(TITLE) -->", item->title);
+ if (strstr (b, "<!-- $(DESCRIPTION) -->") && item->title_description)
+ str_replace (&b, "<!-- $(DESCRIPTION) -->", item->title_description);
+ if (strstr (b, "<!-- $(TOTAL_ITEMS) -->")) {
+ s1 = g_strdup_printf ("%d", parent_items->items->len);
+ str_replace (&b, "<!-- $(TOTAL_ITEMS) -->", s1);
+ g_free (s1);
+ }
+ if (strstr (b, "<!-- $(FILE_NO) -->")) {
+ s1 = g_strdup_printf ("%d", item_index);
+ str_replace(&b, "<!-- $(FILE_NO) -->", s1);
+ g_free (s1);
+ }
+ if (strstr (b, "<!-- $(NAV_BAR) -->")) {
+ s1 = g_strconcat (item->title, " (", item->path, ")", NULL);
+ parent = parent_items;
+ level = 0;
+ while (parent) {
+ s3 = make_string ("../", level);
+ s2 = g_strconcat ("<a href=\"", s3, "index.html\">", parent->ID, "</a> &gt; ", s1, NULL);
+ free (s3);
+ g_free (s1);
+ s1 = s2;
+ parent = parent->parent_index;
+ level++;
+ }
+ str_replace (&b, "<!-- $(NAV_BAR) -->", s1);
+ g_free (s1);
+ }
+ if (strstr (b, "<!-- $(IMG_SRC_BIG) -->")) {
+ s1 = g_strconcat (IMG_BIG_DIR, "/", item->path, NULL);
+ str_replace (&b, "<!-- $(IMG_SRC_BIG) -->", s1);
+ g_free (s1);
+ }
+ if (strstr(b, "<!-- $(IMG_SRC_FULL) -->")) {
+ s1 = g_strconcat (IMG_ORIG_DIR, "/", item->path, NULL);
+ str_replace (&b, "<!-- $(IMG_SRC_FULL) -->", s1);
+ g_free (s1);
+ }
+ if (strstr(b, "<!-- $(IMG_SIZE_BIG_W) -->")) {
+ s1 = g_strdup_printf ("%lu", img_big_w);
+ str_replace (&b, "<!-- $(IMG_SIZE_BIG_W) -->", s1);
+ g_free (s1);
+ }
+ if (strstr(b, "<!-- $(IMG_SIZE_BIG_H) -->")) {
+ s1 = g_strdup_printf ("%lu", img_big_h);
+ str_replace (&b, "<!-- $(IMG_SIZE_BIG_H) -->", s1);
+ g_free (s1);
+ }
+ if (strstr(b, "<!-- $(IMG_SIZE_ORIG_W) -->")) {
+ s1 = g_strdup_printf ("%lu", img_orig_w);
+ str_replace (&b, "<!-- $(IMG_SIZE_ORIG_W) -->", s1);
+ g_free (s1);
+ }
+ if (strstr(b, "<!-- $(IMG_SIZE_ORIG_H) -->")) {
+ s1 = g_strdup_printf ("%lu", img_orig_h);
+ str_replace (&b, "<!-- $(IMG_SIZE_ORIG_H) -->", s1);
+ g_free (s1);
+ }
+
+ if (strstr (b, "<!-- $(EXIF_ISO) -->")) {
+ if (exif->iso)
+ str_replace (&b, "<!-- $(EXIF_ISO) -->", exif->iso);
+ else
+ str_replace (&b, "<!-- $(EXIF_ISO) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_TIME) -->")) {
+ if (exif->exposure)
+ str_replace (&b, "<!-- $(EXIF_TIME) -->", exif->exposure);
+ else
+ str_replace (&b, "<!-- $(EXIF_TIME) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_APERTURE) -->")) {
+ if (exif->aperture)
+ str_replace (&b, "<!-- $(EXIF_APERTURE) -->", exif->aperture);
+ else
+ str_replace (&b, "<!-- $(EXIF_APERTURE) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_FOCAL_LENGTH) -->")) {
+ if (exif->focal_length)
+ str_replace (&b, "<!-- $(EXIF_FOCAL_LENGTH) -->", exif->focal_length);
+ else
+ str_replace (&b, "<!-- $(EXIF_FOCAL_LENGTH) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_FLASH) -->")) {
+ if (exif->flash)
+ str_replace (&b, "<!-- $(EXIF_FLASH) -->", exif->flash);
+ else
+ str_replace (&b, "<!-- $(EXIF_FLASH) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_DATE) -->")) {
+ if (exif->datetime)
+ str_replace (&b, "<!-- $(EXIF_DATE) -->", exif->datetime);
+ else
+ str_replace (&b, "<!-- $(EXIF_DATE) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_CAMERA_MODEL) -->")) {
+ if (exif->camera_model)
+ str_replace (&b, "<!-- $(EXIF_CAMERA_MODEL) -->", exif->camera_model);
+ else
+ str_replace (&b, "<!-- $(EXIF_CAMERA_MODEL) -->", "??");
+ }
+ if (strstr (b, "<!-- $(EXIF_FOCAL_35) -->")) {
+ if (exif->focal_length_35mm) {
+ s1 = g_strconcat ("(", exif->focal_length_35mm, ")", NULL);
+ str_replace (&b, "<!-- $(EXIF_FOCAL_35) -->", s1);
+ g_free (s1);
+ }
+ else
+ str_replace (&b, "<!-- $(EXIF_FOCAL_35) -->", "");
+ }
+
+ if (strstr (b, "<!-- $(LINK_NEXT) -->")) {
+ if (next_item) {
+ s1 = g_strconcat (next_item->path, ".html", NULL);
+ str_replace (&b, "<!-- $(LINK_NEXT) -->", s1);
+ g_free (s1);
+ }
+ else
+ str_replace (&b, "<!-- $(LINK_NEXT) -->", "index.html");
+ }
+ if (strstr(b, "<!-- $(LINK_PREV) -->")) {
+ if (previous_item) {
+ s1 = g_strconcat (previous_item->path, ".html", NULL);
+ str_replace (&b, "<!-- $(LINK_PREV) -->", s1);
+ g_free (s1);
+ }
+ else
+ str_replace (&b, "<!-- $(LINK_PREV) -->", "index.html");
+ }
+
+ if (strstr (b, "<!-- $(FOOTER) -->"))
+ str_replace (&b, "<!-- $(FOOTER) -->", setup->footer);
+
+ if (! fputs (b, fout)) {
+ fprintf (stderr, "write_html_image: error writing to file \"%s\": %s\n", dst, strerror (errno));
+ res = FALSE;
+ free (b);
+ break;
+ }
+ free (b);
+ }
+
+ fclose (fout);
+ fclose (fin);
+ free (buffer);
+ free (big_dst);
+ free (orig_dst);
+ free (buf_img_fullsize_link);
+ free_exif_data (exif);
+ return res;
+}
+
+
+/*
+ * build_tree: generate complete gallery tree based on source xml files
+ *
+ * src_tree = source directory of the items
+ * dst_dir = destination of the generated items
+ * parent_index = parent album to determine our descent in the tree
+ *
+ */
+gboolean
+build_tree (TGallerySetup *setup,
+ const char *src_tree,
+ const char *dst_dir,
+ TAlbum *parent_index)
+{
+ char *idx_file;
+ TAlbum *items;
+ TIndexItem *item;
+ char *s1, *s2, *s3;
+ char *thumb_dir;
+ char *img_big_dir;
+ char *img_orig_dir;
+ char *template;
+ gboolean res;
+ int i;
+
+ printf ("*** Entering directory '%s'\n", src_tree);
+ #ifdef __DEBUG_ALL__
+ printf ("setup->real_templates_dir = %s\n", setup->real_templates_dir);
+ #endif
+
+ /* Check access permissions */
+ if (access (src_tree, R_OK | X_OK)) {
+ fprintf (stderr, "error accessing source directory: %s\n", strerror (errno));
+ return FALSE;
+ }
+ if (access (dst_dir, R_OK | W_OK | X_OK)) {
+ if (mkdir (dst_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
+ fprintf (stderr, "error creating destination directory: %s\n", strerror (errno));
+ return FALSE;
+ }
+ }
+
+ /* Check the index file */
+ idx_file = g_strconcat (src_tree, "/index.xml", NULL);
+ if (access (src_tree, R_OK | X_OK)) {
+ fprintf (stderr, "error accessing index file '%s': %s\n", idx_file, strerror (errno));
+ g_free (idx_file);
+ return FALSE;
+ }
+
+ /* Read the index file and fill items array */
+ items = malloc (sizeof (TAlbum));
+ if (! parse_album_xml (idx_file, items)) {
+ fprintf (stderr, "error reading index file '%s'\n", idx_file);
+ g_free (idx_file);
+ free_album_data (items);
+ return FALSE;
+ }
+ g_free (idx_file);
+ items->parent_index = parent_index;
+
+
+ /* Copy support files */
+ if (setup->verbose) printf ("Writing '%s' ...", setup->styles);
+ s1 = g_strconcat (setup->real_templates_dir, "/", setup->styles, NULL);
+ s2 = g_strconcat (dst_dir, "/", setup->styles, NULL);
+ copy_file (s1, s2);
+ g_free (s1);
+ g_free (s2);
+ if (setup->verbose) printf (" done.\n");
+
+ if (setup->verbose) printf ("Writing '%s' ...", setup->scripts);
+ s1 = g_strconcat (setup->real_templates_dir, "/", setup->scripts, NULL);
+ s2 = g_strconcat (dst_dir, "/", setup->scripts, NULL);
+ copy_file (s1, s2);
+ g_free (s1);
+ g_free (s2);
+ if (setup->verbose) printf (" done.\n");
+
+
+ /* Prepare target thumbnail directory */
+ thumb_dir = g_strconcat (dst_dir, "/", THUMBNAIL_DIR, NULL);
+ if (access (thumb_dir, R_OK | W_OK | X_OK))
+ if (mkdir (thumb_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
+ fprintf (stderr, "error making target thumbnail directory: %s\n", strerror (errno));
+ g_free (thumb_dir);
+ free_album_data (items);
+ return FALSE;
+ }
+ g_free (thumb_dir);
+
+ /* Prepare target preview and orig directories */
+ if (items->type == GALLERY_TYPE_ALBUM)
+ {
+ res = TRUE;
+ img_big_dir = g_strconcat (dst_dir, "/", IMG_BIG_DIR, NULL);
+ img_orig_dir = g_strconcat (dst_dir, "/", IMG_ORIG_DIR, NULL);
+ if (access (img_big_dir, R_OK | W_OK | X_OK))
+ if (mkdir (img_big_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
+ fprintf (stderr, "error making target preview directory: %s\n", strerror (errno));
+ res = FALSE;
+ }
+ if (access (img_orig_dir, R_OK | W_OK | X_OK))
+ if (mkdir (img_orig_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
+ fprintf (stderr, "error making target full size directory: %s\n", strerror (errno));
+ res = FALSE;
+ }
+ g_free (img_big_dir);
+ g_free (img_orig_dir);
+ if (! res) {
+ free_album_data (items);
+ return FALSE;
+ }
+ }
+
+
+ /* Start generating items */
+ if (items->type == GALLERY_TYPE_INDEX)
+ template = g_strconcat ("/", setup->template_index, NULL);
+ else
+ if (items->type == GALLERY_TYPE_ALBUM)
+ template = g_strconcat ("/", setup->template_album, NULL);
+
+ if (setup->verbose) printf ("Writing 'index.html' ...\n");
+ s1 = g_strconcat (setup->real_templates_dir, template, NULL);
+ s2 = g_strconcat (dst_dir, "/index.html", NULL);
+ res = write_html_album (setup, s1, s2, items);
+ g_free (s1);
+ g_free (s2);
+ g_free (template);
+ if (! res) {
+ fprintf (stderr, "error generating target index file\n");
+ free_album_data (items);
+ return FALSE;
+ }
+ if (setup->verbose) printf (" done.\n");
+
+
+ /* Recurse to sub-albums (in case of album index) */
+ if (items->type == GALLERY_TYPE_INDEX)
+ {
+ if (items->items->len > 0) {
+ for (i = 0; i < items->items->len; i++) {
+ item = g_ptr_array_index (items->items, i);
+ if (item == NULL) {
+ fprintf (stderr, "build_tree: error getting item %d\n", i);
+ continue;
+ }
+ s1 = g_strconcat (src_tree, "/", item->path, "/", NULL);
+ s2 = g_strconcat (dst_dir, "/", item->path, "/", NULL);
+ build_tree (setup, s1, s2, items);
+ g_free (s1);
+ g_free (s2);
+ }
+ }
+ }
+
+ /* Generate separate image pages (in case of album) */
+ if (items->type == GALLERY_TYPE_ALBUM)
+ {
+ if (items->items->len > 0) {
+ for (i = 0; i < items->items->len; i++) {
+ item = g_ptr_array_index (items->items, i);
+ if (item == NULL) {
+ fprintf (stderr, "build_tree: error getting item %d\n", i);
+ continue;
+ }
+ if (setup->verbose) printf ("Writing '%s.html' ...", item->path);
+ s1 = g_strconcat (setup->real_templates_dir, "/", setup->template_photo, NULL);
+ s2 = g_strconcat (items->base_dir, "/", item->path, NULL);
+ s3 = g_strconcat (dst_dir, "/", item->path, ".html", NULL);
+ res = write_html_image (setup, s1, s2, s3, item, items);
+ g_free (s1);
+ g_free (s2);
+ g_free (s3);
+ if (! res ) continue;
+ if (setup->verbose) printf (" done.\n");
+ }
+ }
+ }
+
+ printf ("*** Leaving directory '%s'\n", src_tree);
+ free_album_data (items);
+
+ return TRUE;
+}