From: Lutz M?l. <lu...@us...> - 2003-07-24 20:18:15
|
Update of /cvsroot/libexif/libmnote/libmnote/olympus In directory sc8-pr-cvs1:/tmp/cvs-serv21220/libmnote/olympus Modified Files: mnote-olympus-data.c mnote-olympus-entry.c mnote-olympus-entry.h mnote-olympus-tag.c mnote-olympus-tag.h Log Message: 2003-07-24 Lutz Mueller <lu...@us...> * libmnote: Lots of improvements from Al Evans <al...@tb...>. Index: mnote-olympus-data.c =================================================================== RCS file: /cvsroot/libexif/libmnote/libmnote/olympus/mnote-olympus-data.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- mnote-olympus-data.c 15 Dec 2002 11:44:19 -0000 1.3 +++ mnote-olympus-data.c 24 Jul 2003 20:18:11 -0000 1.4 @@ -77,6 +77,23 @@ return (value); } +#ifdef DEBUG +// Look at memory around p +static void dump_memory_around(const unsigned char *p) +{ + static char *format = "%xl %xl %xl %xl\n"; + static unsigned buf[4]; + unsigned int i; + + for (i = 0; i < 5; i++) { + memcpy(buf, p - 32 + (16 * i), sizeof(buf)); + printf(format, buf[0], buf[1], buf[2], buf[3]); + } + +} +#endif + + static void mnote_olympus_data_load_data_entry (MNoteOlympusData *note, MNoteOlympusEntry *entry, @@ -85,6 +102,7 @@ { unsigned int s, doff; ExifByteOrder order = mnote_data_get_byte_order ((MNoteData *) note); + const unsigned char *d_orig = d; entry->tag = exif_get_short (d + offset + 0, order); entry->format = exif_get_short (d + offset + 2, order); @@ -95,24 +113,54 @@ * in the entry but somewhere else (offset). */ s = exif_format_get_size (entry->format) * entry->components; +#ifdef DEBUG + printf ("exif get size is %i ", exif_format_get_size (entry->format)); + printf ("entry format is %i, #components is %li, ", + entry->format, entry->components); + printf ("entry size is %i\n", s); +#endif if (!s) return; - if (s > 4) + if (s > 4) { + + /* + THIS DOES NOT WORK! + The problem is that d points to the first MakerNote Tag. + According to the EXIF 2.1 spec, it should point to the + TIFF header preceding the EXIF information. + I have tried rolling it back by 10 bytes (pointing to the + OLYMP) and by 18 bytes (assuming the TIFF header immediately + precedes the OLYMP). Neither of these hacks produced any + meaningful data within 32 bytes of the pointer, for a + case in which I know the desired values of the numerator + and denominator of a rational. + */ doff = exif_get_long (d + offset + 8, order); - else + d_orig = d + doff; +#ifdef DEBUG + printf("**** data offset is %i\n", doff); + dump_memory_around(d_orig); +#endif + } + else { doff = offset + 8; + d_orig = d + doff; + } + /* Sanity check */ - if (size < doff + s) + /* This doesn't work if the data is outside the tag!! */ + if ((s <= 4) && (size < doff + s)) return; entry->data = malloc (sizeof (char) * s); if (!entry->data) return; entry->size = s; - memcpy (entry->data, d + doff, s); + memcpy (entry->data, d_orig, s); } + static void mnote_olympus_data_load_data (MNoteData *en, const unsigned char *data, unsigned int size) @@ -120,51 +168,84 @@ MNoteOlympusData *note = (MNoteOlympusData *) en; MNoteOlympusTag tag; MNoteOlympusEntry *entry; - unsigned int i, n; - ExifByteOrder order = mnote_data_get_byte_order (en); - /* Verify the header */ - if ((size < 5) || memcmp (data, "OLYMP", 5)) - return; - data += 5; - size -= 5; - - /* 2 unknown bytes */ - if ((size < 2) || (data[0] != 0x00) || (data[1] != 0x01)) - return; - data += 2; - size -= 2; - - /* Number of entries */ - if (size < 2) - return; - n = exif_get_short (data, order); + // Check for reality and usefulness + // -- needs to start with OLYMP + // -- if < 22 bytes, hasn't got space for any entries + if ((size < 22) || memcmp(data, "OLYMP", 5)) { #ifdef DEBUG - printf ("Reading %i entries...\n", n); + printf("Olympus maker note malformed or too small\n"); #endif - data += 2; - size -= 2; - - /* 2 unknown bytes */ - if ((size < 2) || (data[0] != 0x00) || (data[1] != 0x00)) return; - data += 2; - size -= 2; + } + else { + ExifByteOrder order = mnote_data_get_byte_order (en); + short nEntries = exif_get_short (data + 8, order); + const unsigned char *tagEntries = data + 10; + unsigned int i; - for (i = 0; i < n; i++) { - tag = exif_get_short (data + 12 * i, order); + for (i = 0; i < nEntries; i++) { + tag = exif_get_short (tagEntries + 12 * i, order); #ifdef DEBUG - printf ("Loading entry '%s' (%i)...\n", - mnote_olympus_tag_get_name (tag), i + 1); + printf ("Loading entry '%s' (%x) (%i)...\n", + mnote_olympus_tag_get_name (tag), tag, i + 1); #endif entry = mnote_olympus_entry_new (); mnote_olympus_data_add_entry (note, entry); - mnote_olympus_data_load_data_entry (note, entry, data, size, + mnote_olympus_data_load_data_entry (note, entry, tagEntries, size, 12 * i); mnote_olympus_entry_unref (entry); } + } + + +} +static unsigned int +mnote_olympus_get_count (MNoteData *n) +{ + MNoteOlympusData *note = (MNoteOlympusData *) n; + + return (note->count); } +static MNoteEntry * +mnote_olympus_get_entry (MNoteData *n, MNoteTag t) +{ + MNoteOlympusData *note = (MNoteOlympusData *) n; + MNoteOlympusTag tag = (MNoteOlympusTag) t; + unsigned int i; + MNoteEntry *entry = NULL; + + for (i = 0; !entry && i < note->count; i++) { + if (note->entries[i]->tag == tag) { + entry = note->entries[i]; + } + } + + return (entry); +} + +static void +mnote_olympus_foreach_entry (MNoteData *n, MNoteDataForeachEntryFunc func, void *data) +{ + MNoteOlympusData *note = (MNoteOlympusData *) n; + unsigned int i; + + if (!note || !func) { +#ifdef DEBUG + if (!note) printf("No note in foreach_entry\n"); + if (!func) printf("No func in foreach_entry\n"); +#endif + return; + } + printf("In mnote_olympus_foreach_entry for %d entries\n", note->count); + for (i = 0; i < note->count; i++) { + printf ("Calling func for i = %i\n", i); + func (n, (MNoteTag)note->entries[i]->tag, data); + } +} + + MNoteData * mnote_olympus_data_new (void) { @@ -177,8 +258,12 @@ mnote_data_construct ((MNoteData *) note); ((MNoteData *) note)->methods.free = mnote_olympus_data_free; ((MNoteData *) note)->methods.load_data = mnote_olympus_data_load_data; + ((MNoteData *) note)->methods.get_count = mnote_olympus_get_count; + ((MNoteData *) note)->methods.get_entry = mnote_olympus_get_entry; + ((MNoteData *) note)->methods.foreach_entry = mnote_olympus_foreach_entry; ((MNoteData *) note)->methods.get_tag_name = mnote_olympus_tag_get_name; ((MNoteData *) note)->methods.get_value = mnote_olympus_data_get_value; + ((MNoteData *) note)->methods.dump_entry = mnote_olympus_entry_dump; return ((MNoteData *) note); } Index: mnote-olympus-entry.h =================================================================== RCS file: /cvsroot/libexif/libmnote/libmnote/olympus/mnote-olympus-entry.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- mnote-olympus-entry.h 15 Dec 2002 11:44:19 -0000 1.2 +++ mnote-olympus-entry.h 24 Jul 2003 20:18:11 -0000 1.3 @@ -51,4 +51,6 @@ char *mnote_olympus_entry_get_value (MNoteOlympusEntry *entry); +void mnote_olympus_entry_dump (MNoteEntry *entry, unsigned int indent); + #endif /* __MNOTE_OLYMPUS_ENTRY_H__ */ Index: mnote-olympus-tag.c =================================================================== RCS file: /cvsroot/libexif/libmnote/libmnote/olympus/mnote-olympus-tag.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- mnote-olympus-tag.c 15 Dec 2002 11:44:19 -0000 1.4 +++ mnote-olympus-tag.c 24 Jul 2003 20:18:11 -0000 1.5 @@ -34,13 +34,19 @@ {MNOTE_OLYMPUS_TAG_QUALITY, "Quality", N_("Quality"), ""}, {MNOTE_OLYMPUS_TAG_MACRO, "Macro", N_("Macro"), ""}, {MNOTE_OLYMPUS_TAG_UNKNOWN_1, "Unknown1", N_("Unknown 1"), ""}, - {MNOTE_OLYMPUS_TAG_ZOOM, "Zoom", N_("Zoom"), ""}, + {MNOTE_OLYMPUS_TAG_DIGIZOOM, "DigiZoom", N_("Digital Zoom"), ""}, {MNOTE_OLYMPUS_TAG_UNKNOWN_2, "Unknown2", N_("Unknown 2"), ""}, {MNOTE_OLYMPUS_TAG_UNKNOWN_3, "Unknown3", N_("Unknown 3"), ""}, {MNOTE_OLYMPUS_TAG_VERSION, "FirmwareVersion", N_("Firmware version"), ""}, {MNOTE_OLYMPUS_TAG_INFO, "Info", N_("Info"), ""}, {MNOTE_OLYMPUS_TAG_ID, "CameraID", N_("Camera ID"), ""}, {MNOTE_OLYMPUS_TAG_UNKNOWN_4, "Unknown4", N_("Unknown 4"), ""}, + {MNOTE_OLYMPUS_TAG_FLASHMODE, "FlashMode", N_("Flash Mode"), ""}, + {MNOTE_OLYMPUS_TAG_FOCUSDIST, "ManualFocusDistance", N_("Manual Focus Distance"), ""}, + {MNOTE_OLYMPUS_TAG_SHARPNESS, "Sharpness", N_("Sharpness Setting"), ""}, + {MNOTE_OLYMPUS_TAG_WBALANCE, "WhiteBalance", N_("White Balance Setting"), ""}, + {MNOTE_OLYMPUS_TAG_CONTRAST, "Contrast", N_("Contrast Setting"), ""}, + {MNOTE_OLYMPUS_TAG_MANFOCUS, "ManualFocus", N_("Manual Focus"), ""}, {0, NULL, NULL, NULL} }; Index: mnote-olympus-tag.h =================================================================== RCS file: /cvsroot/libexif/libmnote/libmnote/olympus/mnote-olympus-tag.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- mnote-olympus-tag.h 15 Dec 2002 11:44:19 -0000 1.2 +++ mnote-olympus-tag.h 24 Jul 2003 20:18:11 -0000 1.3 @@ -32,13 +32,19 @@ MNOTE_OLYMPUS_TAG_QUALITY = 0x0201, MNOTE_OLYMPUS_TAG_MACRO = 0x0202, MNOTE_OLYMPUS_TAG_UNKNOWN_1 = 0x0203, - MNOTE_OLYMPUS_TAG_ZOOM = 0x0204, + MNOTE_OLYMPUS_TAG_DIGIZOOM = 0x0204, MNOTE_OLYMPUS_TAG_UNKNOWN_2 = 0x0205, MNOTE_OLYMPUS_TAG_UNKNOWN_3 = 0x0206, MNOTE_OLYMPUS_TAG_VERSION = 0x0207, MNOTE_OLYMPUS_TAG_INFO = 0x0208, MNOTE_OLYMPUS_TAG_ID = 0x0209, - MNOTE_OLYMPUS_TAG_UNKNOWN_4 = 0x0f04 + MNOTE_OLYMPUS_TAG_UNKNOWN_4 = 0x0f04, + MNOTE_OLYMPUS_TAG_FLASHMODE = 0x1004, + MNOTE_OLYMPUS_TAG_MANFOCUS = 0x100b, + MNOTE_OLYMPUS_TAG_FOCUSDIST = 0x100c, + MNOTE_OLYMPUS_TAG_SHARPNESS = 0x100f, + MNOTE_OLYMPUS_TAG_WBALANCE = 0x1015, + MNOTE_OLYMPUS_TAG_CONTRAST = 0x1029 }; typedef enum _MNoteOlympusTag MNoteOlympusTag; Index: mnote-olympus-entry.c =================================================================== RCS file: /cvsroot/libexif/libmnote/libmnote/olympus/mnote-olympus-entry.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- mnote-olympus-entry.c 15 Dec 2002 11:44:19 -0000 1.4 +++ mnote-olympus-entry.c 24 Jul 2003 20:18:11 -0000 1.5 @@ -43,7 +43,7 @@ return (NULL); memset (entry, 0, sizeof (MNoteOlympusEntry)); - entry->priv = malloc (sizeof (MNoteOlympusEntry)); + entry->priv = malloc (sizeof (MNoteOlympusEntryPrivate)); if (!entry->priv) { mnote_olympus_entry_free (entry); return (NULL); @@ -94,6 +94,34 @@ free (entry); } +void +mnote_olympus_entry_dump (MNoteEntry *e, unsigned int indent) +{ + MNoteOlympusEntry *entry = (MNoteOlympusEntry *)e; + + char buf[1024]; + unsigned int i; + + for (i = 0; i < 2 * indent; i++) + buf[i] = ' '; + buf[i] = '\0'; + + if (!e) { + printf("No entry in mnote_olympus_entry_dump!\n"); + return; + } + + printf ("%sTag: 0x%x ('%s')\n", buf, entry->tag, + mnote_olympus_tag_get_name (entry->tag)); + printf ("%s Format: %i ('%s')\n", buf, entry->format, + exif_format_get_name (entry->format)); + printf ("%s Components: %i\n", buf, (int) entry->components); + printf ("%s Size: %i\n", buf, entry->size); + if (entry->size > 0) { + printf ("%s Value: %s\n", buf, mnote_olympus_entry_get_value (entry)); + } +} + #define CF(format,target,v) \ { \ if (format != target) { \ @@ -125,6 +153,7 @@ ExifByteOrder order; ExifLong vl; ExifShort vs; + ExifRational vr; if (!entry) return (NULL); @@ -219,7 +248,7 @@ CC (entry->components, 1, v); strncpy (v, _("Unknown tag."), sizeof (v)); break; - case MNOTE_OLYMPUS_TAG_ZOOM: + case MNOTE_OLYMPUS_TAG_DIGIZOOM: CF (entry->format, EXIF_FORMAT_SHORT, v); CC (entry->components, 1, v); vs = exif_get_short (entry->data, order); @@ -258,6 +287,147 @@ case MNOTE_OLYMPUS_TAG_UNKNOWN_4: CF (entry->format, EXIF_FORMAT_LONG, v); CC (entry->components, 30, v); + break; + case MNOTE_OLYMPUS_TAG_FLASHMODE: + CF (entry->format, EXIF_FORMAT_SHORT, v); + CC (entry->components, 1, v); + vs = exif_get_short (entry->data, order); + switch (vs) { + case 0: + strncpy (v, _("Auto"), sizeof (v)); + break; + case 1: + strncpy (v, _("Red-eye reduction"), sizeof (v)); + break; + case 2: + strncpy (v, _("Fill"), sizeof (v)); + break; + case 3: + strncpy (v, _("Off"), sizeof (v)); + break; + default: + snprintf (buf, sizeof (buf), "%i", vs); + strncpy (v, buf, sizeof (v)); + } + break; + case MNOTE_OLYMPUS_TAG_FOCUSDIST: + CF (entry->format, EXIF_FORMAT_RATIONAL, v); + CC (entry->components, 1, v); + vr = exif_get_rational (entry->data, order); + if (vr.numerator == 0) { + strncpy (v, _("Unknown"), sizeof (v)); + } + else { + unsigned long tmp = vr.numerator / vr.denominator; +// printf("numerator %li, denominator %li\n", vr.numerator, vr.denominator); + snprintf (v, sizeof (v), "%li mm", tmp); + } + break; + case MNOTE_OLYMPUS_TAG_SHARPNESS: + CF (entry->format, EXIF_FORMAT_SHORT, v); + CC (entry->components, 1, v); + vs = exif_get_short (entry->data, order); + switch (vs) { + case 0: + strncpy (v, _("Normal"), sizeof (v)); + break; + case 1: + strncpy (v, _("Hard"), sizeof (v)); + break; + case 2: + strncpy (v, _("Soft"), sizeof (v)); + break; + default: + snprintf (buf, sizeof (buf), "%i", vs); + strncpy (v, buf, sizeof (v)); + } + break; + case MNOTE_OLYMPUS_TAG_WBALANCE: + CF (entry->format, EXIF_FORMAT_SHORT, v); + CC (entry->components, 2, v); + vs = exif_get_short (entry->data, order); + switch (vs) { + case 1: + strncpy (v, _("Automatic"), sizeof (v)); + break; + case 2: + { + ExifShort v2 = exif_get_short (entry->data + 2, order); + unsigned long colorTemp = 0; + switch (v2) { + case 2: + colorTemp = 3000; + break; + case 3: + colorTemp = 3700; + break; + case 4: + colorTemp = 4000; + break; + case 5: + colorTemp = 4500; + break; + case 6: + colorTemp = 5500; + break; + case 7: + colorTemp = 6500; + break; + case 9: + colorTemp = 7500; + break; + } + if (colorTemp) { + snprintf (v, sizeof (v), "Manual: %liK", colorTemp); + } + else { + strncpy (v, _("Manual: Unknown"), sizeof (v)); + } + + } + break; + case 3: + strncpy (v, _("One-touch"), sizeof (v)); + break; + default: + strncpy (v, _("Unknown"), sizeof (v)); + break; + } + break; + case MNOTE_OLYMPUS_TAG_CONTRAST: + CF (entry->format, EXIF_FORMAT_SHORT, v); + CC (entry->components, 1, v); + vs = exif_get_short (entry->data, order); + switch (vs) { + case 0: + strncpy (v, _("Hard"), sizeof (v)); + break; + case 1: + strncpy (v, _("Normal"), sizeof (v)); + break; + case 2: + strncpy (v, _("Soft"), sizeof (v)); + break; + default: + snprintf (buf, sizeof (buf), "%i", vs); + strncpy (v, buf, sizeof (v)); + } + break; + case MNOTE_OLYMPUS_TAG_MANFOCUS: + CF (entry->format, EXIF_FORMAT_SHORT, v); + CC (entry->components, 1, v); + vs = exif_get_short (entry->data, order); + switch (vs) { + case 0: + strncpy (v, _("No"), sizeof (v)); + break; + case 1: + strncpy (v, _("Yes"), sizeof (v)); + break; + default: + snprintf (buf, sizeof (buf), "%i", vs); + strncpy (v, buf, sizeof (v)); + } break; default: break; |