diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-07-27 19:13:28 +0200 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-07-27 19:13:28 +0200 |
| commit | 510fff156db65795cbf211e7910a67fb316cb404 (patch) | |
| tree | dfbec486ffeab2d6886f9f51863f723a2d5cd574 /jpeg-utils.c | |
| download | cataract-510fff156db65795cbf211e7910a67fb316cb404.tar.xz | |
Initial commitv0.99.0
Diffstat (limited to 'jpeg-utils.c')
| -rw-r--r-- | jpeg-utils.c | 280 |
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; + } +} + |
