comparison src/format_canon.c @ 47:aa4c0e1b54b0

Fri Jun 3 01:49:20 2005 John Ellis <johne@verizon.net> * 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. #####
author gqview
date Fri, 03 Jun 2005 06:07:02 +0000
parents 7cfa60beda76
children 6948407f52a5
comparison
equal deleted inserted replaced
46:905f8fa583a3 47:aa4c0e1b54b0
28 28
29 #include "intl.h" 29 #include "intl.h"
30 30
31 #include "format_canon.h" 31 #include "format_canon.h"
32 #include "format_raw.h" 32 #include "format_raw.h"
33
34 #include "exif.h"
33 35
34 36
35 #if 0 37 #if 0
36 #define CANON_DEBUG 38 #define CANON_DEBUG
37 #endif 39 #endif
468 #undef DEBUG_ENTRY 470 #undef DEBUG_ENTRY
469 #undef DEBUG_EXIT 471 #undef DEBUG_EXIT
470 472
471 } 473 }
472 474
473 475 /*
476 *-----------------------------------------------------------------------------
477 * EXIF Makernote for Canon
478 *-----------------------------------------------------------------------------
479 */
480
481 typedef struct _CanonTag CanonTag;
482 struct _CanonTag {
483 guint id;
484 const gchar *description;
485 ExifTextList *list;
486 };
487
488 static ExifTextList CanonSet1MacroMode[] = {
489 { 1, "macro" },
490 { 2, "normal" },
491 EXIF_TEXT_LIST_END
492 };
493
494 static ExifTextList CanonSet1Quality[] = {
495 { 2, "normal" },
496 { 3, "fine" },
497 { 5, "superfine" },
498 EXIF_TEXT_LIST_END
499 };
500
501 static ExifTextList CanonSet1FlashMode[] = {
502 { 0, "flash not fired" },
503 { 1, "auto" },
504 { 2, "on" },
505 { 3, "red eye reduction" },
506 { 4, "slow synchro" },
507 { 5, "auto with red eye reduction" },
508 { 6, "on with red eye reduction" },
509 { 16, "external flash" },
510 EXIF_TEXT_LIST_END
511 };
512
513 static ExifTextList CanonSet1DriveMode[] = {
514 { 0, "single or timer" },
515 { 1, "continuous" },
516 EXIF_TEXT_LIST_END
517 };
518
519 static ExifTextList CanonSet1FocusMode[] = {
520 { 0, "one-shot" },
521 { 1, "AI servo" },
522 { 2, "AI focus" },
523 { 3, "manual" },
524 { 4, "single" },
525 { 5, "continuous" },
526 { 6, "manual" },
527 EXIF_TEXT_LIST_END
528 };
529
530 static ExifTextList CanonSet1ImageSize[] = {
531 { 0, "large" },
532 { 1, "medium" },
533 { 2, "small" },
534 /* where (or) does Medium 1/2 fit in here ? */
535 EXIF_TEXT_LIST_END
536 };
537
538 static ExifTextList CanonSet1ShootingMode[] = {
539 { 0, "auto" },
540 { 1, "manual" },
541 { 2, "landscape" },
542 { 3, "fast shutter" },
543 { 4, "slow shutter" },
544 { 5, "night" },
545 { 6, "black and white" },
546 { 7, "sepia" },
547 { 8, "portrait" },
548 { 9, "sports" },
549 { 10, "macro" },
550 { 11, "panoramic focus" },
551 EXIF_TEXT_LIST_END
552 };
553
554 /* Don't think this is interpreted correctly/completely, A60 at 2.5x Digital sets value of 3 */
555 static ExifTextList CanonSet1DigitalZoom[] = {
556 { 0, "none" },
557 { 1, "2x" },
558 { 2, "4x" },
559 EXIF_TEXT_LIST_END
560 };
561
562 static ExifTextList CanonSet1ConSatSharp[] = {
563 { 0, "normal" },
564 { 1, "high" },
565 { 65535,"low" },
566 EXIF_TEXT_LIST_END
567 };
568
569 static ExifTextList CanonSet1ISOSpeed[] = {
570 /* { 0, "not set/see EXIF tag" }, */
571 { 15, "auto" },
572 { 16, "50" },
573 { 17, "100" },
574 { 18, "200" },
575 { 19, "400" },
576 EXIF_TEXT_LIST_END
577 };
578
579 static ExifTextList CanonSet1MeteringMode[] = {
580 { 3, "evaluative" },
581 { 4, "partial" },
582 { 5, "center-weighted" },
583 EXIF_TEXT_LIST_END
584 };
585
586 static ExifTextList CanonSet1FocusType[] = {
587 { 0, "manual" },
588 { 1, "auto" },
589 { 3, "macro" },
590 { 8, "locked" },
591 EXIF_TEXT_LIST_END
592 };
593
594 static ExifTextList CanonSet1AutoFocusPoint[] = {
595 { 12288, "manual focus" },
596 { 12289, "auto" },
597 { 12290, "right" },
598 { 12291, "center" },
599 { 12292, "left" },
600 EXIF_TEXT_LIST_END
601 };
602
603 static ExifTextList CanonSet1ExposureMode[] = {
604 { 0, "auto" },
605 { 1, "program" },
606 { 2, "Tv priority" },
607 { 3, "Av priority" },
608 { 4, "manual" },
609 { 5, "A-DEP" },
610 EXIF_TEXT_LIST_END
611 };
612
613 static ExifTextList CanonSet1FlashFired[] = {
614 { 0, "no" },
615 { 1, "yes" },
616 EXIF_TEXT_LIST_END
617 };
618
619 static ExifTextList CanonSet1FocusCont[] = {
620 { 0, "no (single)" },
621 { 1, "yes" },
622 EXIF_TEXT_LIST_END
623 };
624
625 static ExifMarker CanonSet1[] = {
626 /* 0 is length of array in bytes (2 x array size) */
627 { 1, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.MacroMode", "Macro mode", CanonSet1MacroMode },
628 { 2, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.SelfTimer", "Self timer (10ths of second)", NULL },
629 { 3, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Quality", "Quality", CanonSet1Quality },
630 { 4, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashMode", "Flash mode", CanonSet1FlashMode },
631 { 5, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.DriveMode", "Drive mode", CanonSet1DriveMode },
632 { 7, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocusMode", "Focus mode", CanonSet1FocusMode },
633 { 10, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ImageSize", "Image size", CanonSet1ImageSize },
634 { 11, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ShootingMode","Shooting mode", CanonSet1ShootingMode },
635 { 11, EXIF_FORMAT_SHORT_UNSIGNED, 1, "ExposureProgram", "ExposureProgram", CanonSet1ShootingMode },
636 { 12, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.DigitalZoom", "Digital zoom", CanonSet1DigitalZoom },
637 { 13, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Contrast", "Contrast", CanonSet1ConSatSharp },
638 { 14, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Saturation", "Saturation", CanonSet1ConSatSharp },
639 { 15, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.Sharpness", "Sharpness", CanonSet1ConSatSharp },
640 { 16, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ISOSpeed", "ISO speed", CanonSet1ISOSpeed },
641 { 16, EXIF_FORMAT_SHORT_UNSIGNED, 1, "ISOSpeedRatings", "ISO speed", CanonSet1ISOSpeed },
642 { 17, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.MeteringMode","Metering mode", CanonSet1MeteringMode },
643 { 18, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocusType", "Focus type", CanonSet1FocusType },
644 { 19, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.AutoFocus", "AutoFocus point", CanonSet1AutoFocusPoint },
645 { 20, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ExposureMode","Exposure mode", CanonSet1ExposureMode },
646 { 20, EXIF_FORMAT_SHORT_UNSIGNED, 1, "ExposureMode", "Exposure mode", CanonSet1ExposureMode },
647 { 23, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocalLengthLong","Long focal length", NULL },
648 { 24, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocalLengthShort","Short focal length", NULL },
649 { 25, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FocalLengthUnits","Focal units per mm", NULL },
650 { 28, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashFired", "Flash fired", CanonSet1FlashFired },
651 { 29, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashDetails","Flash details", NULL },
652 { 32, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.ContinuousFocus","Continuous focus", CanonSet1FocusCont },
653 EXIF_MARKER_LIST_END
654 };
655
656 static ExifTextList CanonSet2WhiteBalance[] = {
657 { 0, "auto" },
658 { 1, "sunny" },
659 { 2, "cloudy" },
660 { 3, "tungsten" },
661 { 4, "flourescent" },
662 { 5, "flash" },
663 { 6, "custom" },
664 EXIF_TEXT_LIST_END
665 };
666
667 static ExifTextList CanonSet2FlashBias[] = {
668 { 0x0000, "0" },
669 { 0x000c, "0.33" },
670 { 0x0010, "0.5" },
671 { 0x0014, "0.67" },
672 { 0x0020, "1" },
673 { 0x002c, "1.33" },
674 { 0x0030, "1.5" },
675 { 0x0034, "1.67" },
676 { 0x0040, "2" },
677 { 0xffc0, "-2" },
678 { 0xffcc, "-1.67" },
679 { 0xffd0, "-1.5" },
680 { 0xffd4, "-1.33" },
681 { 0xffe0, "-1" },
682 { 0xffec, "-0.67" },
683 { 0xfff0, "-0.5" },
684 { 0xfff4, "-0.33" },
685 EXIF_TEXT_LIST_END
686 };
687
688 static ExifMarker CanonSet2[] = {
689 /* 0 is length of array in bytes (2 x array size) */
690 { 7, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.WhiteBalance","White balance", CanonSet2WhiteBalance },
691 { 7, EXIF_FORMAT_SHORT_UNSIGNED, 1, "LightSource", "White balance", CanonSet2WhiteBalance },
692 { 9, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.SequenceNumber","Sequence number", NULL },
693 { 15, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.FlashBias", "Flash bias", CanonSet2FlashBias },
694 /* distance needs more than just this (metric) value */
695 { 19, EXIF_FORMAT_SHORT_UNSIGNED, 1, "MkN.Canon.SubjectDistance", "Subject Distance", NULL },
696 EXIF_MARKER_LIST_END
697 };
698
699 #if 0
700
701 static ExifTextList CanonCustomEnable[] = {
702 { 0, "off" },
703 { 1, "on" },
704 EXIF_TEXT_LIST_END
705 };
706
707 static ExifTextList CanonCustomEnableInvert[] = {
708 { 0, "on" },
709 { 1, "off" },
710 EXIF_TEXT_LIST_END
711 };
712
713 static ExifTextList CanonCustomExposureLevel[] = {
714 { 0, "1/2 stop" },
715 { 1, "1/3 stop" },
716 EXIF_TEXT_LIST_END
717 };
718
719 static ExifTextList CanonCustomAVShutterSpeed[] = {
720 { 0, "auto" },
721 { 1, "1/200 (fixed)" },
722 EXIF_TEXT_LIST_END
723 };
724
725 static ExifTextList CanonCustomShutterCurtainSync[] = {
726 { 0, "1st" },
727 { 1, "2nd" },
728 EXIF_TEXT_LIST_END
729 };
730
731 static CanonTag CanonCustom[] = {
732 { 1, "Noise reduction", CanonCustomEnable },
733 /* { 2, "Shutter/Auto Exposure Button Function", CanonCustomBTNShutter }, */
734 { 3, "Mirror lockup", CanonCustomEnable },
735 { 4, "Tv/Av and exposure level", CanonCustomExposureLevel },
736 { 5, "AF assist light", CanonCustomEnableInvert },
737 { 6, "Shutter speed in Av mode", CanonCustomAVShutterSpeed },
738 /* { 7, "Auto-Exposure bracketting sequence/auto cancellation", CanonCustom }, */
739 { 8, "Shutter sync", CanonCustomShutterCurtainSync },
740 /* { 9, "AF button function", CanonCustom }, */
741 { 10, "Fill flash auto reduction", CanonCustomEnableInvert },
742 /* { 11, "Menu button function", CanonCustom }, */
743 /* { 12, "Set button function", CanonCustom }, */
744 { 13, "Sensor cleaning", CanonCustomEnable },
745 { 0, NULL, NULL }
746 };
747
748 #endif
749
750 static ExifMarker CanonExifMarkersList[] = {
751 { 1, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Canon.Settings1", NULL, NULL },
752 { 4, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Canon.Settings2", NULL, NULL },
753 { 6, EXIF_FORMAT_STRING, -1, "MkN.Canon.ImageType", "Image type", NULL },
754 { 7, EXIF_FORMAT_STRING, -1, "MkN.Canon.FirmwareVersion", "Firmware version", NULL },
755 { 8, EXIF_FORMAT_LONG_UNSIGNED, 1, "MkN.Canon.ImageNumber", "Image number", NULL },
756 { 9, EXIF_FORMAT_STRING, -1, "MkN.Canon.OwnerName", "Owner name", NULL },
757 { 12, EXIF_FORMAT_BYTE_UNSIGNED, -1, "MkN.Canon.SerialNumber", "Camera serial number", NULL },
758 { 15, EXIF_FORMAT_SHORT_UNSIGNED, -1, "MkN.Canon.CustomFunctions", NULL, NULL },
759 EXIF_MARKER_LIST_END
760 };
761
762 static void canon_mknote_parse_settings(ExifData *exif,
763 guint16 *data, guint32 len, int byte_order,
764 ExifMarker *list)
765 {
766 gint i;
767
768 i = 0;
769 while (list[i].tag != 0)
770 {
771 if (list[i].tag < len)
772 {
773 ExifItem *item;
774
775 item = exif_item_new(EXIF_FORMAT_SHORT_UNSIGNED, list[i].tag, 1, &list[i]);
776 exif_item_copy_data(item, &data[list[i].tag], 1, EXIF_FORMAT_SHORT_UNSIGNED, byte_order);
777 exif->items = g_list_prepend(exif->items, item);
778 }
779
780 i++;
781 }
782 }
783
784 #if 0
785 static void canon_mknote_parse_convert(ExifData *exif)
786 {
787 gint value;
788
789 /* seems we need more than only this value for distance */
790 if (exif_get_integer(exif, "MkN.Canon.SubjectDistance", &value))
791 {
792 static ExifMarker marker= { 0x9206, EXIF_FORMAT_RATIONAL_UNSIGNED, 1,
793 "SubjectDistance", "Subject distance", NULL };
794 ExifItem *item;
795 ExifRational *rational;
796
797 item = exif_item_new(marker.format, marker.tag, 1, &marker);
798 rational = item->data;
799 rational->num = value;
800 rational->den = 100;
801
802 exif->items = g_list_prepend(exif->items, item);
803 }
804
805 /* Serial Number untested */
806 if (exif_get_integer(exif, "MkN.Canon.SerialNumber", &value))
807 {
808 static ExifMarker marker= { 12, EXIF_FORMAT_STRING, -1,
809 "SerialNumber", "Camera serial number", NULL };
810 ExifItem *item;
811 gchar *text;
812 gint l;
813
814 text = g_strdup_printf("%04X%05d", value & 0xff00 >> 8, value & 0x00ff);
815 l = strlen(text);
816 item = exif_item_new(marker.format, marker.tag, l, &marker);
817 memcpy(item->data, text, l);
818 g_free(text);
819
820 exif->items = g_list_prepend(exif->items, item);
821 }
822 }
823 #endif
824
825 gint format_exif_makernote_canon_parse(ExifData *exif, unsigned char *tiff, int offset,
826 int size, int byte_order)
827 {
828 ExifItem *item;
829 gchar *text;
830 gint found;
831
832 text = exif_get_data_as_text(exif, "Make");
833 found = (text && strncasecmp(text, "Canon", 5) == 0);
834 g_free(text);
835
836 if (!found ||
837 exif_parse_IFD_table(exif, tiff, offset, size, byte_order, CanonExifMarkersList) != 0)
838 {
839 return FALSE;
840 }
841
842 item = exif_get_item(exif, "MkN.Canon.Settings1");
843 if (item)
844 {
845 canon_mknote_parse_settings(exif, item->data, item->data_len, byte_order, CanonSet1);
846 }
847
848 item = exif_get_item(exif, "MkN.Canon.Settings2");
849 if (item)
850 {
851 canon_mknote_parse_settings(exif, item->data, item->data_len, byte_order, CanonSet2);
852 }
853
854 #if 0
855 canon_mknote_parse_convert(exif);
856 #endif
857
858 return TRUE;
859 }
860
861