From 1fabd8ba0601e861b6385b2b230da5f6b6cc5f0b Mon Sep 17 00:00:00 2001 From: Lutz Mueller Date: Mon, 15 Apr 2002 10:55:02 +0200 Subject: [PATCH] =?utf8?q?2002-04-15=20=20Lutz=20M=C3=BCller=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Enhancements by Semyon Sosin , adapted: * libexif/exif-entry.c (exif_entry_get_value): More tags covered. * libexif/exif-data.c (exif_data_new_from_file): Don't read the whole file into memory. --- ChangeLog | 8 +++++ libexif/exif-data.c | 37 +++++++++++++++++++--- libexif/exif-entry.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 125 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c127878..aca9638 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2002-04-15 Lutz Müller + + Enhancements by Semyon Sosin , adapted: + + * libexif/exif-entry.c (exif_entry_get_value): More tags covered. + * libexif/exif-data.c (exif_data_new_from_file): Don't read the whole + file into memory. + 2002-04-04 Hans Ulrich Niedermann * Makefile.am: dded .tar.bz2 packaging to "make dist" diff --git a/libexif/exif-data.c b/libexif/exif-data.c index d3c2bc2..e926945 100644 --- a/libexif/exif-data.c +++ b/libexif/exif-data.c @@ -582,15 +582,41 @@ exif_data_new_from_file (const char *path) unsigned int size; unsigned char *data; ExifData *edata; + int marker, ll, lh; f = fopen (path, "rb"); if (!f) return (NULL); - /* For now, we read the data into memory. Patches welcome... */ - fseek (f, 0, SEEK_END); - size = ftell (f); - fseek (f, 0, SEEK_SET); + while (1) { + while ((marker = fgetc (f)) == 0xff); + + /* JPEG_MARKER_SOI */ + if (marker == JPEG_MARKER_SOI) + continue; + + /* JPEG_MARKER_APP0 */ + if (marker == JPEG_MARKER_APP0) { + lh = fgetc (f); + ll = fgetc (f); + size = (lh << 8) | ll; + if (fseek (f, size - 2, SEEK_CUR) < 0) + return (NULL); + continue; + } + + /* JPEG_MARKER_APP1 */ + if (marker == JPEG_MARKER_APP1) + break; + + /* Unknown marker or data. Give up. */ + return (NULL); + } + + /* EXIF data found. Allocate the necessary memory and read the data. */ + lh = fgetc (f); + ll = fgetc (f); + size = (lh << 8) | ll; data = malloc (sizeof (char) * size); if (!data) return (NULL); @@ -695,6 +721,9 @@ void exif_data_foreach_content (ExifData *data, ExifDataForeachContentFunc func, void *user_data) { + if (!data || !func) + return; + func (data->ifd0, user_data); func (data->ifd1, user_data); func (data->ifd_exif, user_data); diff --git a/libexif/exif-entry.c b/libexif/exif-entry.c index 7a03c7b..007b65a 100644 --- a/libexif/exif-entry.c +++ b/libexif/exif-entry.c @@ -150,6 +150,8 @@ exif_entry_get_value (ExifEntry *e) static char v[1024], b[1024]; const char *c; ExifByteOrder o; + double d; + ExifEntry *entry; /* We need the byte order */ if (!e || !e->parent || !e->parent->parent) @@ -190,20 +192,88 @@ exif_entry_get_value (ExifEntry *e) strncat (v, "[None]", sizeof (v)); strncat (v, " (Editor)", sizeof (v)); break; + case EXIF_TAG_FNUMBER: + CF (e->format, EXIF_FORMAT_RATIONAL, v); + CC (e->components, 1, v); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) + return (NULL); + snprintf (v, sizeof (v), "f/%.01f", (float) v_rat.numerator / + (float) v_rat.denominator); + break; case EXIF_TAG_APERTURE_VALUE: CF (e->format, EXIF_FORMAT_RATIONAL, v); CC (e->components, 1, v); v_rat = exif_get_rational (e->data, o); - snprintf (b, sizeof (b), "%i/%i", (int) v_rat.numerator, - (int) v_rat.denominator); - snprintf (v, sizeof (v), "%s (APEX: f%.01f)", b, + if (!v_rat.denominator) + return (NULL); + snprintf (v, sizeof (v), "f/%.01f", pow (2 , ((float) v_rat.numerator / (float) v_rat.denominator) / 2.)); break; + case EXIF_TAG_FOCAL_LENGTH: + CF (e->format, EXIF_FORMAT_RATIONAL, v); + CC (e->components, 1, v); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) + return (NULL); + + /* + * For calculation of the 35mm equivalent, + * Minolta cameras need a multiplier that depends on the + * camera model. + */ + d = 0.; + entry = exif_content_get_entry (e->parent->parent->ifd0, + EXIF_TAG_MAKE); + if (entry && entry->data && + !strncmp (entry->data, "Minolta", 7)) { + entry = exif_content_get_entry (e->parent->parent->ifd0, + EXIF_TAG_MODEL); + if (entry && entry->data) { + if (!strncmp (entry->data, "DiMAGE 7", 8)) + d = 3.9; + else if (!strncmp (entry->data, "DiMAGE 5", 8)) + d = 4.9; + } + } + if (d) + snprintf (b, sizeof (b), _(" (35 equivalent: %d mm)"), + (int) (d * (double) v_rat.numerator / + (double) v_rat.denominator)); + + snprintf (v, sizeof (v), "%.1f mm%s", + (float) v_rat.numerator / (float) v_rat.denominator, + b); + break; + case EXIF_TAG_SUBJECT_DISTANCE: + CF (e->format, EXIF_FORMAT_RATIONAL, v); + CC (e->components, 1, v); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) + return (NULL); + snprintf (v, sizeof (v), "%.1f m", (float) v_rat.numerator / + (float) v_rat.denominator); + break; + case EXIF_TAG_EXPOSURE_TIME: + CF (e->format, EXIF_FORMAT_RATIONAL, v); + CC (e->components, 1, v); + v_rat = exif_get_rational (e->data, o); + if (!v_rat.denominator) + return (NULL); + d = (double) v_srat.numerator / (double) v_srat.denominator; + if (d < 1) + snprintf (v, sizeof (v), _("1/%d sec."), + (int) (1. / d)); + else + snprintf (v, sizeof (v), _("%d sec."), (int) d); + break; case EXIF_TAG_SHUTTER_SPEED_VALUE: CF (e->format, EXIF_FORMAT_SRATIONAL, v); CC (e->components, 1, v); v_srat = exif_get_srational (e->data, o); + if (!v_rat.denominator) + return (NULL); snprintf (b, sizeof (b), "%.0f/%.0f sec.", (float) v_srat.numerator, (float) v_srat.denominator); snprintf (v, sizeof (v), "%s (APEX: %i)", b, @@ -493,6 +563,17 @@ exif_entry_get_value (ExifEntry *e) break; } break; + case EXIF_TAG_EXPOSURE_BIAS_VALUE: + CF (e->format, EXIF_FORMAT_SRATIONAL, v); + CC (e->components, 1, v); + v_srat = exif_get_srational (e->data, o); + if (!v_srat.denominator) + return (NULL); + snprintf (v, sizeof (v), "%s%.01f", + v_srat.denominator * v_srat.numerator > 0 ? "+" : "", + (double) v_srat.numerator / + (double) v_srat.denominator); + break; case EXIF_TAG_ORIENTATION: CF (e->format, EXIF_FORMAT_SHORT, v); CC (e->components, 1, v); -- 2.7.4