Mercurial > geeqie.yaz
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 |