From afcb746e4946a7932caad188dc36ac9c4ada11df Mon Sep 17 00:00:00 2001 From: John Ellis Date: Fri, 3 Jun 2005 06:07:02 +0000 Subject: [PATCH] Fri Jun 3 01:49:20 2005 John Ellis * exif.[ch]: Export several parsing functions for use by the exif makernote parsers, and add hook for MakerNote data parsing. * format_canon.[ch]: Add Canon EXIF MakerNote support. * format_raw.c: Fix warning printf grammar. ##### Note: GQview CVS on sourceforge is not always up to date, please use ##### ##### an offical release when making enhancements and translation updates. ##### --- ChangeLog | 7 + src/exif.c | 59 ++++--- src/exif.h | 20 ++- src/format_canon.c | 388 +++++++++++++++++++++++++++++++++++++++++++++ src/format_canon.h | 7 + src/format_raw.c | 2 +- 6 files changed, 457 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3cd5f154..6be1ac60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri Jun 3 01:49:20 2005 John Ellis + + * exif.[ch]: Export several parsing functions for use by the exif + makernote parsers, and add hook for MakerNote data parsing. + * format_canon.[ch]: Add Canon EXIF MakerNote support. + * format_raw.c: Fix warning printf grammar. + Thu May 26 22:14:53 2005 John Ellis * format_raw.c (format_raw_parse): Use unsigned int to match arguments. diff --git a/src/exif.c b/src/exif.c index ff229f45..485083d3 100644 --- a/src/exif.c +++ b/src/exif.c @@ -73,6 +73,8 @@ #include "format_raw.h" #include "ui_fileops.h" +/* makernote parsers */ +#include "format_canon.h" /* *----------------------------------------------------------------------------- @@ -99,6 +101,7 @@ ExifFormatAttrib ExifFormatList[] = { /* tags that are special, or need special treatment */ #define TAG_EXIFOFFSET 0x8769 +#define TAG_EXIFMAKERNOTE 0x927c /* @@ -107,8 +110,6 @@ ExifFormatAttrib ExifFormatList[] = { *----------------------------------------------------------------------------- */ -#define EXIF_TEXT_LIST_END { -1, NULL } - static ExifTextList ExifOrientationList[] = { { EXIF_ORIENTATION_UNKNOWN, N_("unknown") }, { EXIF_ORIENTATION_TOP_LEFT, N_("top left") }, @@ -393,8 +394,7 @@ ExifMarker ExifKnownMarkersList[] = { { 0x9215, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, "ExposureIndex", NULL, NULL }, { 0x9216, EXIF_FORMAT_BYTE_UNSIGNED, 4, "TIFF/EPStandardID", NULL, NULL }, - /* end is marked by 0 tag */ -{ 0x0000, EXIF_FORMAT_UNKNOWN, 0, NULL, NULL, NULL } +EXIF_MARKER_LIST_END }; ExifMarker ExifUnknownMarkersList[] = { @@ -461,9 +461,7 @@ typedef struct __attribute__((packed)) { } IFDEntry; -static ExifMarker *exif_marker_from_tag(uint16_t tag); -static int parse_IFD_table(ExifData *exif, unsigned char *tiff, int offset, - int size, int byte_order); +static const ExifMarker *exif_marker_from_tag(uint16_t tag, const ExifMarker *list); /* *----------------------------------------------------------------------------- @@ -471,7 +469,8 @@ static int parse_IFD_table(ExifData *exif, unsigned char *tiff, int offset, *----------------------------------------------------------------------------- */ -static ExifItem *exif_item_new(ExifFormatType format, unsigned int tag, unsigned int elements, ExifMarker *marker) +ExifItem *exif_item_new(ExifFormatType format, unsigned int tag, + unsigned int elements, const ExifMarker *marker) { ExifItem *item; @@ -714,17 +713,18 @@ static int goto_next_marker(unsigned char **f, int *size, int *marker) *------------------------------------------------------------------- */ -static ExifMarker *exif_marker_from_tag(uint16_t tag) +static const ExifMarker *exif_marker_from_tag(uint16_t tag, const ExifMarker *list) { - static int len = sizeof(ExifKnownMarkersList)/sizeof(ExifMarker) - 1; int i = 0; - while (i < len && ExifKnownMarkersList[i].tag != tag) + if (!list) return NULL; + + while (list[i].tag != 0 && list[i].tag != tag) { i++; } - return (i >= len ? NULL : &ExifKnownMarkersList[i]); + return (list[i].tag == 0 ? NULL : &list[i]); } static void rational_from_data(ExifRational *r, void *src, int byte_order) @@ -733,7 +733,7 @@ static void rational_from_data(ExifRational *r, void *src, int byte_order) r->den = swab_int32(*(uint32_t*)(src + sizeof(uint32_t)), byte_order); } -static void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_format, int byte_order) +void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_format, int byte_order) { int bs; int ne; @@ -818,14 +818,15 @@ static void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatTy } } -static int parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset, - int size, int byte_order) +static int exif_parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset, + int size, int byte_order, + const ExifMarker *list) { IFDEntry *ent = (IFDEntry*)(tiff+offset); uint32_t swabed_data; void *data; int data_len; - ExifMarker *marker; + const ExifMarker *marker; ExifItem *item; ent->tag = swab_int16(ent->tag, byte_order); @@ -836,7 +837,7 @@ static int parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset, /* Check tag type. If it does not match, either the format is wrong, * either it is a unknown tag; so it is not really an error. */ - marker = exif_marker_from_tag(ent->tag); + marker = exif_marker_from_tag(ent->tag, list); if (!marker) { if (ent->format > EXIF_FORMAT_DOUBLE) @@ -901,16 +902,26 @@ static int parse_IFD_entry(ExifData *exif, unsigned char *tiff, int offset, exif_item_copy_data(item, data, data_len, ent->format, byte_order); exif->items = g_list_prepend(exif->items, item); - if (item->tag == TAG_EXIFOFFSET) + if (list == ExifKnownMarkersList) { - parse_IFD_table(exif, tiff, swabed_data, size, byte_order); + switch (item->tag) + { + case TAG_EXIFOFFSET: + exif_parse_IFD_table(exif, tiff, swabed_data, size, byte_order, list); + break; + case TAG_EXIFMAKERNOTE: + format_exif_makernote_canon_parse(exif, tiff, swabed_data, size, byte_order); + break; + } } return 0; } -static int parse_IFD_table(ExifData *exif, unsigned char *tiff, int offset, - int size, int byte_order) +int exif_parse_IFD_table(ExifData *exif, + unsigned char *tiff, int offset, + int size, int byte_order, + const ExifMarker *list) { int i, nb_entries; @@ -924,7 +935,7 @@ static int parse_IFD_table(ExifData *exif, unsigned char *tiff, int offset, for (i=0; iIFD_offset, byte_order); - return parse_IFD_table(exif, tiff, offset, size, byte_order); + return exif_parse_IFD_table(exif, tiff, offset, size, byte_order, ExifKnownMarkersList); } static int parse_JPEG(ExifData *exif, unsigned char *f, int size) @@ -1132,7 +1143,7 @@ ExifItem *exif_get_item(ExifData *exif, const gchar *key) gchar *exif_item_get_data_as_text(ExifItem *item) { - ExifMarker *marker; + const ExifMarker *marker; gpointer data; GString *string; gchar *text; diff --git a/src/exif.h b/src/exif.h index 5298dd32..f13828ff 100644 --- a/src/exif.h +++ b/src/exif.h @@ -90,7 +90,7 @@ struct _ExifItem { ExifFormatType format; int tag; - ExifMarker *marker; + const ExifMarker *marker; int elements; gpointer data; int data_len; @@ -106,12 +106,16 @@ struct _ExifMarker ExifTextList *list; }; +#define EXIF_MARKER_LIST_END { 0x0000, EXIF_FORMAT_UNKNOWN, 0, NULL, NULL, NULL } + struct _ExifTextList { int value; const char* description; }; +#define EXIF_TEXT_LIST_END { -1, NULL } + typedef struct _ExifFormattedText ExifFormattedText; struct _ExifFormattedText @@ -188,4 +192,18 @@ const gchar *exif_get_description_by_key(const gchar *key); void exif_write_data_list(ExifData *exif, FILE *f, gint human_readable_list); + +/* These funcs for use by makernote parsers only */ + +ExifItem *exif_item_new(ExifFormatType format, unsigned int tag, + unsigned int elements, const ExifMarker *marker); +void exif_item_copy_data(ExifItem *item, void *src, int len, ExifFormatType src_format, int byte_order); + +gint exif_parse_IFD_table(ExifData *exif, + unsigned char *tiff, int offset, + int size, int byte_order, + const ExifMarker *list); + + + #endif diff --git a/src/format_canon.c b/src/format_canon.c index f6ff838c..1749257c 100644 --- a/src/format_canon.c +++ b/src/format_canon.c @@ -31,6 +31,8 @@ #include "format_canon.h" #include "format_raw.h" +#include "exif.h" + #if 0 #define CANON_DEBUG @@ -470,4 +472,390 @@ return_only: } +/* + *----------------------------------------------------------------------------- + * EXIF Makernote for Canon + *----------------------------------------------------------------------------- + */ + +typedef struct _CanonTag CanonTag; +struct _CanonTag { + guint id; + const gchar *description; + ExifTextList *list; +}; + +static ExifTextList CanonSet1MacroMode[] = { + { 1, "macro" }, + { 2, "normal" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1Quality[] = { + { 2, "normal" }, + { 3, "fine" }, + { 5, "superfine" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1FlashMode[] = { + { 0, "flash not fired" }, + { 1, "auto" }, + { 2, "on" }, + { 3, "red eye reduction" }, + { 4, "slow synchro" }, + { 5, "auto with red eye reduction" }, + { 6, "on with red eye reduction" }, + { 16, "external flash" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1DriveMode[] = { + { 0, "single or timer" }, + { 1, "continuous" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1FocusMode[] = { + { 0, "one-shot" }, + { 1, "AI servo" }, + { 2, "AI focus" }, + { 3, "manual" }, + { 4, "single" }, + { 5, "continuous" }, + { 6, "manual" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1ImageSize[] = { + { 0, "large" }, + { 1, "medium" }, + { 2, "small" }, + /* where (or) does Medium 1/2 fit in here ? */ + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1ShootingMode[] = { + { 0, "auto" }, + { 1, "manual" }, + { 2, "landscape" }, + { 3, "fast shutter" }, + { 4, "slow shutter" }, + { 5, "night" }, + { 6, "black and white" }, + { 7, "sepia" }, + { 8, "portrait" }, + { 9, "sports" }, + { 10, "macro" }, + { 11, "panoramic focus" }, + EXIF_TEXT_LIST_END +}; + +/* Don't think this is interpreted correctly/completely, A60 at 2.5x Digital sets value of 3 */ +static ExifTextList CanonSet1DigitalZoom[] = { + { 0, "none" }, + { 1, "2x" }, + { 2, "4x" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1ConSatSharp[] = { + { 0, "normal" }, + { 1, "high" }, + { 65535,"low" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1ISOSpeed[] = { +/* { 0, "not set/see EXIF tag" }, */ + { 15, "auto" }, + { 16, "50" }, + { 17, "100" }, + { 18, "200" }, + { 19, "400" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1MeteringMode[] = { + { 3, "evaluative" }, + { 4, "partial" }, + { 5, "center-weighted" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1FocusType[] = { + { 0, "manual" }, + { 1, "auto" }, + { 3, "macro" }, + { 8, "locked" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1AutoFocusPoint[] = { + { 12288, "manual focus" }, + { 12289, "auto" }, + { 12290, "right" }, + { 12291, "center" }, + { 12292, "left" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1ExposureMode[] = { + { 0, "auto" }, + { 1, "program" }, + { 2, "Tv priority" }, + { 3, "Av priority" }, + { 4, "manual" }, + { 5, "A-DEP" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1FlashFired[] = { + { 0, "no" }, + { 1, "yes" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet1FocusCont[] = { + { 0, "no (single)" }, + { 1, "yes" }, + EXIF_TEXT_LIST_END +}; + +static ExifMarker CanonSet1[] = { +/* 0 is length of array in bytes (2 x array size) */ +{ 1, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.MacroMode", "Macro mode", CanonSet1MacroMode }, +{ 2, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.SelfTimer", "Self timer (10ths of second)", NULL }, +{ 3, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Quality", "Quality", CanonSet1Quality }, +{ 4, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashMode", "Flash mode", CanonSet1FlashMode }, +{ 5, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.DriveMode", "Drive mode", CanonSet1DriveMode }, +{ 7, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocusMode", "Focus mode", CanonSet1FocusMode }, +{ 10, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ImageSize", "Image size", CanonSet1ImageSize }, +{ 11, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ShootingMode","Shooting mode", CanonSet1ShootingMode }, + { 11, EXIF_FORMAT_SHORT_UNSIGNED, 1, "ExposureProgram", "ExposureProgram", CanonSet1ShootingMode }, +{ 12, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.DigitalZoom", "Digital zoom", CanonSet1DigitalZoom }, +{ 13, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Contrast", "Contrast", CanonSet1ConSatSharp }, +{ 14, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Saturation", "Saturation", CanonSet1ConSatSharp }, +{ 15, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Sharpness", "Sharpness", CanonSet1ConSatSharp }, +{ 16, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ISOSpeed", "ISO speed", CanonSet1ISOSpeed }, + { 16, EXIF_FORMAT_SHORT_UNSIGNED, 1, "ISOSpeedRatings", "ISO speed", CanonSet1ISOSpeed }, +{ 17, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.MeteringMode","Metering mode", CanonSet1MeteringMode }, +{ 18, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocusType", "Focus type", CanonSet1FocusType }, +{ 19, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.AutoFocus", "AutoFocus point", CanonSet1AutoFocusPoint }, +{ 20, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ExposureMode","Exposure mode", CanonSet1ExposureMode }, + { 20, EXIF_FORMAT_SHORT_UNSIGNED, 1, "ExposureMode", "Exposure mode", CanonSet1ExposureMode }, +{ 23, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocalLengthLong","Long focal length", NULL }, +{ 24, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocalLengthShort","Short focal length", NULL }, +{ 25, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocalLengthUnits","Focal units per mm", NULL }, +{ 28, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashFired", "Flash fired", CanonSet1FlashFired }, +{ 29, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashDetails","Flash details", NULL }, +{ 32, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ContinuousFocus","Continuous focus", CanonSet1FocusCont }, +EXIF_MARKER_LIST_END +}; + +static ExifTextList CanonSet2WhiteBalance[] = { + { 0, "auto" }, + { 1, "sunny" }, + { 2, "cloudy" }, + { 3, "tungsten" }, + { 4, "flourescent" }, + { 5, "flash" }, + { 6, "custom" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonSet2FlashBias[] = { + { 0x0000, "0" }, + { 0x000c, "0.33" }, + { 0x0010, "0.5" }, + { 0x0014, "0.67" }, + { 0x0020, "1" }, + { 0x002c, "1.33" }, + { 0x0030, "1.5" }, + { 0x0034, "1.67" }, + { 0x0040, "2" }, + { 0xffc0, "-2" }, + { 0xffcc, "-1.67" }, + { 0xffd0, "-1.5" }, + { 0xffd4, "-1.33" }, + { 0xffe0, "-1" }, + { 0xffec, "-0.67" }, + { 0xfff0, "-0.5" }, + { 0xfff4, "-0.33" }, + EXIF_TEXT_LIST_END +}; + +static ExifMarker CanonSet2[] = { +/* 0 is length of array in bytes (2 x array size) */ +{ 7, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.WhiteBalance","White balance", CanonSet2WhiteBalance }, + { 7, EXIF_FORMAT_SHORT_UNSIGNED, 1, "LightSource", "White balance", CanonSet2WhiteBalance }, +{ 9, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.SequenceNumber","Sequence number", NULL }, +{ 15, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashBias", "Flash bias", CanonSet2FlashBias }, +/* distance needs more than just this (metric) value */ +{ 19, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.SubjectDistance", "Subject Distance", NULL }, +EXIF_MARKER_LIST_END +}; + +#if 0 + +static ExifTextList CanonCustomEnable[] = { + { 0, "off" }, + { 1, "on" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonCustomEnableInvert[] = { + { 0, "on" }, + { 1, "off" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonCustomExposureLevel[] = { + { 0, "1/2 stop" }, + { 1, "1/3 stop" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonCustomAVShutterSpeed[] = { + { 0, "auto" }, + { 1, "1/200 (fixed)" }, + EXIF_TEXT_LIST_END +}; + +static ExifTextList CanonCustomShutterCurtainSync[] = { + { 0, "1st" }, + { 1, "2nd" }, + EXIF_TEXT_LIST_END +}; + +static CanonTag CanonCustom[] = { + { 1, "Noise reduction", CanonCustomEnable }, +/* { 2, "Shutter/Auto Exposure Button Function", CanonCustomBTNShutter }, */ + { 3, "Mirror lockup", CanonCustomEnable }, + { 4, "Tv/Av and exposure level", CanonCustomExposureLevel }, + { 5, "AF assist light", CanonCustomEnableInvert }, + { 6, "Shutter speed in Av mode", CanonCustomAVShutterSpeed }, +/* { 7, "Auto-Exposure bracketting sequence/auto cancellation", CanonCustom }, */ + { 8, "Shutter sync", CanonCustomShutterCurtainSync }, +/* { 9, "AF button function", CanonCustom }, */ + { 10, "Fill flash auto reduction", CanonCustomEnableInvert }, +/* { 11, "Menu button function", CanonCustom }, */ +/* { 12, "Set button function", CanonCustom }, */ + { 13, "Sensor cleaning", CanonCustomEnable }, + { 0, NULL, NULL } +}; + +#endif + +static ExifMarker CanonExifMarkersList[] = { + { 1, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Canon.Settings1", NULL, NULL }, + { 4, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Canon.Settings2", NULL, NULL }, + { 6, EXIF_FORMAT_STRING, -1, "MkN.Canon.ImageType", "Image type", NULL }, + { 7, EXIF_FORMAT_STRING, -1, "MkN.Canon.FirmwareVersion", "Firmware version", NULL }, + { 8, EXIF_FORMAT_LONG_UNSIGNED, 1, "MkN.Canon.ImageNumber", "Image number", NULL }, + { 9, EXIF_FORMAT_STRING, -1, "MkN.Canon.OwnerName", "Owner name", NULL }, + { 12, EXIF_FORMAT_BYTE_UNSIGNED, -1, "MkN.Canon.SerialNumber", "Camera serial number", NULL }, + { 15, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Canon.CustomFunctions", NULL, NULL }, + EXIF_MARKER_LIST_END +}; + +static void canon_mknote_parse_settings(ExifData *exif, + guint16 *data, guint32 len, int byte_order, + ExifMarker *list) +{ + gint i; + + i = 0; + while (list[i].tag != 0) + { + if (list[i].tag < len) + { + ExifItem *item; + + item = exif_item_new(EXIF_FORMAT_SHORT_UNSIGNED, list[i].tag, 1, &list[i]); + exif_item_copy_data(item, &data[list[i].tag], 1, EXIF_FORMAT_SHORT_UNSIGNED, byte_order); + exif->items = g_list_prepend(exif->items, item); + } + + i++; + } +} + +#if 0 +static void canon_mknote_parse_convert(ExifData *exif) +{ + gint value; + + /* seems we need more than only this value for distance */ + if (exif_get_integer(exif, "MkN.Canon.SubjectDistance", &value)) + { + static ExifMarker marker= { 0x9206, EXIF_FORMAT_RATIONAL_UNSIGNED, 1, + "SubjectDistance", "Subject distance", NULL }; + ExifItem *item; + ExifRational *rational; + + item = exif_item_new(marker.format, marker.tag, 1, &marker); + rational = item->data; + rational->num = value; + rational->den = 100; + + exif->items = g_list_prepend(exif->items, item); + } + + /* Serial Number untested */ + if (exif_get_integer(exif, "MkN.Canon.SerialNumber", &value)) + { + static ExifMarker marker= { 12, EXIF_FORMAT_STRING, -1, + "SerialNumber", "Camera serial number", NULL }; + ExifItem *item; + gchar *text; + gint l; + + text = g_strdup_printf("%04X%05d", value & 0xff00 >> 8, value & 0x00ff); + l = strlen(text); + item = exif_item_new(marker.format, marker.tag, l, &marker); + memcpy(item->data, text, l); + g_free(text); + + exif->items = g_list_prepend(exif->items, item); + } +} +#endif + +gint format_exif_makernote_canon_parse(ExifData *exif, unsigned char *tiff, int offset, + int size, int byte_order) +{ + ExifItem *item; + gchar *text; + gint found; + + text = exif_get_data_as_text(exif, "Make"); + found = (text && strncasecmp(text, "Canon", 5) == 0); + g_free(text); + + if (!found || + exif_parse_IFD_table(exif, tiff, offset, size, byte_order, CanonExifMarkersList) != 0) + { + return FALSE; + } + + item = exif_get_item(exif, "MkN.Canon.Settings1"); + if (item) + { + canon_mknote_parse_settings(exif, item->data, item->data_len, byte_order, CanonSet1); + } + + item = exif_get_item(exif, "MkN.Canon.Settings2"); + if (item) + { + canon_mknote_parse_settings(exif, item->data, item->data_len, byte_order, CanonSet2); + } + +#if 0 + canon_mknote_parse_convert(exif); +#endif + + return TRUE; +} + diff --git a/src/format_canon.h b/src/format_canon.h index ffbdd26f..61eaef24 100644 --- a/src/format_canon.h +++ b/src/format_canon.h @@ -19,6 +19,9 @@ #define __FORMAT_RAW_CANON_H +#include "exif.h" + + gint format_raw_test_canon(const void *data, const guint len, guint *image_offset, guint *exif_offset); @@ -27,5 +30,9 @@ gint format_raw_test_canon(const void *data, const guint len, { "\x49\x49\x2a\00", 4, "Canon cr2 format", format_raw_test_canon } +gint format_exif_makernote_canon_parse(ExifData *exif, unsigned char *tiff, int offset, + int size, int byte_order); + + #endif diff --git a/src/format_raw.c b/src/format_raw.c index 4b035453..ce62c55b 100644 --- a/src/format_raw.c +++ b/src/format_raw.c @@ -130,7 +130,7 @@ gint format_raw_img_exif_offsets_fd(int fd, const void *header_data, const guint map_data = mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0); if (map_data == MAP_FAILED) { - printf("Failed to mmap of file %d\n", fd); + printf("Failed to mmap file %d\n", fd); return FALSE; } -- 2.20.1