#include "stdafx.h" #include "camera_helper.h" //#include <format.h> namespace { namespace internal { template<camera::Property property> struct property_traits {}; template<long Id> struct camera_control_property_traits { typedef IAMCameraControl Interface; static long id() { return Id; } }; template<long Id> struct video_proc_amp_property_traits { typedef IAMVideoProcAmp Interface; static long id() { return Id; } }; template<> struct property_traits < camera::Exposure > : public camera_control_property_traits<CameraControl_Exposure> {}; template<> struct property_traits < camera::Focus > : public camera_control_property_traits<CameraControl_Focus>{}; template<> struct property_traits < camera::Zoom > : public camera_control_property_traits<CameraControl_Zoom>{}; template<> struct property_traits < camera::Pan > : public camera_control_property_traits<CameraControl_Pan>{}; template<> struct property_traits < camera::Tilt > : public camera_control_property_traits<CameraControl_Tilt>{}; template<> struct property_traits < camera::Roll > : public camera_control_property_traits<CameraControl_Roll>{}; template<> struct property_traits < camera::Iris > : public camera_control_property_traits<CameraControl_Iris>{}; template<> struct property_traits < camera::Brightness > : public video_proc_amp_property_traits<VideoProcAmp_Brightness>{}; template<> struct property_traits < camera::Contrast > : public video_proc_amp_property_traits<VideoProcAmp_Contrast>{}; template<> struct property_traits < camera::Hue > : public video_proc_amp_property_traits<VideoProcAmp_Hue>{}; template<> struct property_traits < camera::Saturation > : public video_proc_amp_property_traits<VideoProcAmp_Saturation>{}; template<> struct property_traits < camera::Sharpness > : public video_proc_amp_property_traits<VideoProcAmp_Sharpness>{}; template<> struct property_traits < camera::Gamma > : public video_proc_amp_property_traits<VideoProcAmp_Gamma>{}; template<> struct property_traits < camera::ColorEnable > : public video_proc_amp_property_traits<VideoProcAmp_ColorEnable>{}; template<> struct property_traits < camera::WhiteBalance > : public video_proc_amp_property_traits<VideoProcAmp_WhiteBalance>{}; template<> struct property_traits < camera::BacklightCompensation > : public video_proc_amp_property_traits<VideoProcAmp_BacklightCompensation>{}; template<> struct property_traits < camera::Gain > : public video_proc_amp_property_traits < VideoProcAmp_Gain > {}; template<typename Interface> struct interface_traits {}; template<> struct interface_traits < IAMCameraControl > { static long auto_flag() { return CameraControl_Flags_Auto; } static long manual_flag() { return CameraControl_Flags_Manual; } }; template<> struct interface_traits<IAMVideoProcAmp> { static long auto_flag() { return VideoProcAmp_Flags_Auto; } static long manual_flag() { return VideoProcAmp_Flags_Manual; } }; template<typename Interface, typename SourcePtr> bool has(long id, const SourcePtr& source_ptr) { comet::com_ptr<Interface> pInterface = comet::com_cast(source_ptr); if (!pInterface) return false; long value, flags; HRESULT hr = pInterface->Get(id, &value, &flags); return SUCCEEDED(hr); } template<typename Interface, typename SourcePtr> cam_prop_range get_range(long id, const SourcePtr& source_ptr) { comet::com_ptr<Interface> pInterface = comet::try_cast(source_ptr); cam_prop_range range; long flags; pInterface->GetRange(id, &range.min, &range.max, &range.step, &range.defaultValue, &flags) | comet::raise_exception; range.canBeAuto = (flags & interface_traits<Interface>::auto_flag()) != 0; range.canBeManual = (flags & interface_traits<Interface>::manual_flag()) != 0; return range; } template<typename Interface, typename SourcePtr> cam_prop_value get(long id, const SourcePtr& source_ptr) { comet::com_ptr<Interface> pInterface = comet::try_cast(source_ptr); cam_prop_value value; long flags; pInterface->Get(id, &value.value, &flags) | comet::raise_exception; value.isAuto = (flags & interface_traits<Interface>::auto_flag()) != 0 || (flags & interface_traits<Interface>::manual_flag()) == 0; return value; } template<typename Interface, typename SourcePtr> void set(long id, const cam_prop_value& value, const SourcePtr& source_ptr) { comet::com_ptr<Interface> pInterface = comet::try_cast(source_ptr); long flags = value.isAuto ? interface_traits<Interface>::auto_flag() : interface_traits<Interface>::manual_flag(); pInterface->Set(id, value.value, flags) | comet::raise_exception; } } } #define MAP_OVER_CAMERA_PROPERTIES(FUNC) \ FUNC(::camera::Exposure, Exposure) \ FUNC(::camera::Focus, Focus) \ FUNC(::camera::Zoom, Zoom) \ FUNC(::camera::Pan, Pan) \ FUNC(::camera::Tilt, Tilt) \ FUNC(::camera::Roll, Roll) \ FUNC(::camera::Iris, Iris) \ FUNC(::camera::Brightness, Brightness) \ FUNC(::camera::Contrast, Contrast) \ FUNC(::camera::Hue, Hue) \ FUNC(::camera::Saturation, Saturation) \ FUNC(::camera::Sharpness, Sharpness) \ FUNC(::camera::Gamma, Gamma) \ FUNC(::camera::ColorEnable, Color Enable) \ FUNC(::camera::WhiteBalance, White Balance) \ FUNC(::camera::BacklightCompensation, Backlight Compensation) \ FUNC(::camera::Gain, Gain) bool camera::has(Property property) const { switch (property) { #define CASE(PROP, NAME) case PROP: return ::internal::has<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), source_ptr); MAP_OVER_CAMERA_PROPERTIES(CASE) #undef CASE default: return false; } } cam_prop_range camera::get_range(Property property) const { switch (property) { #define CASE(PROP, NAME) case PROP: return ::internal::get_range<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), source_ptr); MAP_OVER_CAMERA_PROPERTIES(CASE) #undef CASE default: throw std::runtime_error("No such property: " + std::string(camera::property_name(property))); } } cam_prop_value camera::get(Property property) const { switch (property) { #define CASE(PROP, NAME) case PROP: return ::internal::get<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), source_ptr); MAP_OVER_CAMERA_PROPERTIES(CASE) #undef CASE default: throw std::runtime_error("No such property: " + std::string(camera::property_name(property))); } } void camera::set(Property property, const cam_prop_value& value) { switch (property) { #define CASE(PROP, NAME) case PROP: ::internal::set<::internal::property_traits<PROP>::Interface>(::internal::property_traits<PROP>::id(), value, source_ptr); break; MAP_OVER_CAMERA_PROPERTIES(CASE) #undef CASE } } std::vector<camera::Property> camera::list_properties() { std::vector<camera::Property> properties; properties.push_back(Exposure); // CameraControl properties.push_back(Focus); properties.push_back(Zoom); properties.push_back(Pan); properties.push_back(Tilt); properties.push_back(Roll); properties.push_back(Iris); properties.push_back(Brightness); properties.push_back(Contrast); properties.push_back(Hue); properties.push_back(Saturation); properties.push_back(Sharpness); properties.push_back(Gamma); properties.push_back(ColorEnable); properties.push_back(WhiteBalance); properties.push_back(BacklightCompensation); properties.push_back(Gain); return properties; //#define PROPENTRY(PROP, NAME) PROP, // MAP_OVER_CAMERA_PROPERTIES(PROPENTRY) //#undef PROPENTRY // }; } const char* camera::property_name(Property property) { switch (property) { #define CASE(PROP, NAME) case PROP: return #NAME; MAP_OVER_CAMERA_PROPERTIES(CASE) #undef CASE default: return "UNKNOWN"; } }