#include "stdafx.h" #include "camera_helper.h" //#include namespace { namespace internal { template struct property_traits {}; template struct camera_control_property_traits { typedef IAMCameraControl Interface; static long id() { return Id; } }; template 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 {}; template<> struct property_traits < camera::Focus > : public camera_control_property_traits{}; template<> struct property_traits < camera::Zoom > : public camera_control_property_traits{}; template<> struct property_traits < camera::Pan > : public camera_control_property_traits{}; template<> struct property_traits < camera::Tilt > : public camera_control_property_traits{}; template<> struct property_traits < camera::Roll > : public camera_control_property_traits{}; template<> struct property_traits < camera::Iris > : public camera_control_property_traits{}; template<> struct property_traits < camera::Brightness > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::Contrast > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::Hue > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::Saturation > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::Sharpness > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::Gamma > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::ColorEnable > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::WhiteBalance > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::BacklightCompensation > : public video_proc_amp_property_traits{}; template<> struct property_traits < camera::Gain > : public video_proc_amp_property_traits < VideoProcAmp_Gain > {}; template 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 { static long auto_flag() { return VideoProcAmp_Flags_Auto; } static long manual_flag() { return VideoProcAmp_Flags_Manual; } }; template bool has(long id, const SourcePtr& source_ptr) { comet::com_ptr pInterface = comet::com_cast(source_ptr); if (!pInterface) return false; long value, flags; HRESULT hr = pInterface->Get(id, &value, &flags); return SUCCEEDED(hr); } template cam_prop_range get_range(long id, const SourcePtr& source_ptr) { comet::com_ptr 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::auto_flag()) != 0; range.canBeManual = (flags & interface_traits::manual_flag()) != 0; return range; } template cam_prop_value get(long id, const SourcePtr& source_ptr) { comet::com_ptr 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::auto_flag()) != 0 || (flags & interface_traits::manual_flag()) == 0; return value; } template void set(long id, const cam_prop_value& value, const SourcePtr& source_ptr) { comet::com_ptr pInterface = comet::try_cast(source_ptr); long flags = value.isAuto ? interface_traits::auto_flag() : interface_traits::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::Interface>(::internal::property_traits::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::Interface>(::internal::property_traits::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::Interface>(::internal::property_traits::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::Interface>(::internal::property_traits::id(), value, source_ptr); break; MAP_OVER_CAMERA_PROPERTIES(CASE) #undef CASE } } std::vector camera::list_properties() { std::vector 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"; } }