summaryrefslogtreecommitdiff
path: root/jpeg-utils.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 /jpeg-utils.c
downloadcataract-510fff156db65795cbf211e7910a67fb316cb404.tar.xz
Initial commitv0.99.0
Diffstat (limited to 'jpeg-utils.c')
-rw-r--r--jpeg-utils.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/jpeg-utils.c b/jpeg-utils.c
new file mode 100644
index 0000000..dc1c880
--- /dev/null
+++ b/jpeg-utils.c
@@ -0,0 +1,280 @@
+/* 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 <libexif/exif-data.h>
+#include <libexif/exif-content.h>
+#include <libexif/exif-entry.h>
+
+#include <wand/magick-wand.h>
+
+#include "jpeg-utils.h"
+
+
+
+
+/*
+ * get_exif: retrieve EXIF informations from a JPEG image
+ */
+int
+get_exif (const char *filename, TExifData *data)
+{
+ ExifData *edata;
+ ExifEntry *entry;
+ ExifContent *content;
+ int i, j;
+
+ if (data == NULL)
+ data = malloc (sizeof (TExifData));
+ memset (data, 0, sizeof (TExifData));
+ edata = exif_data_new_from_file (filename);
+ if (edata == NULL)
+ return -1;
+
+ for (i = 0; i < EXIF_IFD_COUNT; i++) {
+ content = edata->ifd[i];
+ if ((content == NULL) || (content->count == 0))
+ continue;
+
+ for (j = 0; j < content->count; j++) {
+ entry = content->entries[j];
+
+ if (! content->entries[j])
+ continue;
+
+ #define VALUE_LEN 1024
+ char value[VALUE_LEN + 1];
+
+ switch (entry->tag)
+ {
+ case EXIF_TAG_DATE_TIME:
+ data->datetime = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_DATE_TIME_ORIGINAL:
+ case EXIF_TAG_DATE_TIME_DIGITIZED:
+ if (data->datetime == NULL)
+ data->datetime = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_MODEL:
+ if (data->camera_model == NULL)
+ data->camera_model = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_MAKE:
+ if (data->camera_model == NULL)
+ data->camera_model = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_ISO_SPEED_RATINGS:
+ data->iso = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_FOCAL_LENGTH:
+ data->focal_length = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM:
+ data->focal_length_35mm = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_FNUMBER:
+ data->aperture = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_APERTURE_VALUE:
+ if (data->aperture == NULL)
+ data->aperture = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_EXPOSURE_TIME:
+ data->exposure = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_FLASH:
+ data->flash = strdup (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_PIXEL_X_DIMENSION:
+ data->width = atol (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ case EXIF_TAG_PIXEL_Y_DIMENSION:
+ data->height = atol (exif_entry_get_value (entry, value, VALUE_LEN));
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ exif_data_free (edata);
+
+ #ifdef __DEBUG_ALL__
+ printf("EXIF_TAG_DATE_TIME = %s\n", data->datetime);
+ printf("EXIF_TAG_MODEL = %s\n", data->camera_model);
+ printf("EXIF_TAG_ISO_SPEED_RATINGS = %s\n", data->iso);
+ printf("EXIF_TAG_FOCAL_LENGTH = %s\n", data->focal_length);
+ printf("EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM = %s\n", data->focal_length_35mm);
+ printf("EXIF_TAG_FNUMBER = %s\n", data->aperture);
+ printf("EXIF_TAG_EXPOSURE_TIME = %s\n", data->exposure);
+ printf("EXIF_TAG_FLASH = %s\n", data->flash);
+ printf("EXIF_TAG_PIXEL_X_DIMENSION = %lu\n", data->width);
+ printf("EXIF_TAG_PIXEL_Y_DIMENSION = %lu\n", data->height);
+ #endif
+
+ return 0;
+}
+
+/*
+ * free_exif_struct: free allocated structure
+ */
+void
+free_exif_data (TExifData *data)
+{
+ if (data) {
+ if (data->aperture)
+ free (data->aperture);
+ if (data->camera_model)
+ free (data->camera_model);
+ if (data->datetime)
+ free (data->datetime);
+ if (data->exposure)
+ free (data->exposure);
+ if (data->flash)
+ free (data->flash);
+ if (data->focal_length)
+ free (data->focal_length);
+ if (data->focal_length_35mm)
+ free (data->focal_length_35mm);
+ if (data->iso)
+ free (data->iso);
+ free (data);
+ data = NULL;
+ }
+}
+
+
+/*
+ * resize_image: resize image pointed by src and save result to dst
+ */
+gboolean
+resize_image (const char *src, const char *dst,
+ int size_x, int size_y,
+ int quality)
+{
+ #define ThrowWandException(wand) \
+ { \
+ char *description; \
+ ExceptionType severity; \
+ \
+ description = MagickGetException (wand, &severity); \
+ (void) fprintf (stderr, "Error converting image: %s %s %ld %s\n", GetMagickModule(), description); \
+ description = (char*) MagickRelinquishMemory (description); \
+ return FALSE; \
+ }
+
+ MagickBooleanType status;
+ MagickWand *magick_wand;
+
+ /* Read an image. */
+ MagickWandGenesis();
+ magick_wand = NewMagickWand();
+ status = MagickReadImage (magick_wand, src);
+ if (status == MagickFalse)
+ ThrowWandException (magick_wand);
+ MagickResizeImage (magick_wand, size_x, size_y, LanczosFilter, 1.0);
+ MagickSetImageCompressionQuality (magick_wand, quality);
+
+ /* Write the image and destroy it. */
+ status = MagickWriteImage (magick_wand, dst);
+ if (status == MagickFalse)
+ ThrowWandException (magick_wand);
+ magick_wand = DestroyMagickWand (magick_wand);
+ MagickWandTerminus();
+
+ return TRUE;
+}
+
+
+/*
+ * get_image_sizes: retrieve image dimensions
+ */
+void
+get_image_sizes (const char *img,
+ unsigned long *width, unsigned long *height)
+{
+ #define xThrowWandException(wand) \
+ { \
+ char *description; \
+ ExceptionType severity; \
+ \
+ description = MagickGetException (wand, &severity); \
+ (void) fprintf (stderr, "Error reading image info: %s %s %ld %s\n", GetMagickModule(), description); \
+ description = (char*) MagickRelinquishMemory(description); \
+ return; \
+ }
+
+ MagickBooleanType status;
+ MagickWand *magick_wand;
+
+ *width = -1;
+ *height = -1;
+
+ /* Read an image. */
+ MagickWandGenesis();
+ magick_wand = NewMagickWand();
+ status = MagickPingImage (magick_wand, img);
+ if (status == MagickFalse)
+ xThrowWandException (magick_wand);
+ *width = MagickGetImageWidth (magick_wand);
+ *height = MagickGetImageHeight (magick_wand);
+
+ magick_wand = DestroyMagickWand (magick_wand);
+ MagickWandTerminus();
+}
+
+
+/*
+ * calculate_sizes: calculate maximal image sizes within specified limits keeping aspect ratio
+ */
+void
+calculate_sizes (const unsigned long max_width, const unsigned long max_height,
+ unsigned long *width, unsigned long *height)
+{
+ if ((max_width > *width) && (max_height > *height))
+ return;
+
+ double max_ratio = (double) max_width / (double) max_height;
+ double real_ratio = (double) *width / (double) *height;
+
+ if ((*width > *height) && (max_ratio <= real_ratio))
+ {
+ *height = max_width / real_ratio;
+ *width = max_width;
+ }
+ else
+ {
+ *width = max_height * real_ratio;
+ *height = max_height;
+ }
+}
+