--- /home/ghartinger/src/OpenCV/OpenCV-2.3.1.svn/trunk/opencv/modules/highgui/src/cap_dc1394_v2.cpp
+++ /home/ghartinger/src/OpenCV/OpenCV-2.3.1.svn_patched/trunk/opencv/modules/highgui/src/cap_dc1394_v2.cpp
@@ -260,7 +260,12 @@
 DC1394_FEATURE_TEMPERATURE, //CV_CAP_PROP_TEMPERATURE
 DC1394_FEATURE_TRIGGER, //CV_CAP_PROP_TRIGGER
 DC1394_FEATURE_TRIGGER_DELAY, //CV_CAP_PROP_TRIGGER_DELAY
-DC1394_FEATURE_WHITE_BALANCE//CV_CAP_PROP_WHITE_BALANCE_RED_V
+//GH --->
+DC1394_FEATURE_WHITE_BALANCE,//CV_CAP_PROP_WHITE_BALANCE_RED_V
+DC1394_FEATURE_ZOOM, //CV_CAP_PROP_ZOOM
+DC1394_FEATURE_FOCUS, //CV_CAP_PROP_FOCUS
+-1 //CV_CAP_PROP_GUID
+//GH <---
 };
 CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP()
 {
@@ -303,6 +308,57 @@
                                           DC1394_ISO_SPEED_3200);
     }
 
+
+    //GH --->
+    // should a specific mode be used
+    if (userMode >= 0)
+    {
+        dc1394video_mode_t wantedMode;
+        dc1394video_modes_t videoModes;
+        dc1394_video_get_supported_modes(dcCam, &videoModes);
+
+        //set mode from number, for example the second supported mode, i.e userMode = 1
+        if (userMode < (int)videoModes.num)
+        {
+            wantedMode = videoModes.modes[userMode];
+        }
+
+        //set modes directly from DC134 constants (from dc1394video_mode_t)
+        else if ((userMode >= DC1394_VIDEO_MODE_MIN) && (userMode <= DC1394_VIDEO_MODE_MAX ))
+        {
+            //search for wanted mode, to check if camera supports it
+            int j = 0;
+            while ((j< (int)videoModes.num) && videoModes.modes[j]!=userMode)
+            {
+                j++;
+            }
+            if ((int)videoModes.modes[j]==userMode)
+            {
+                wantedMode = videoModes.modes[j];
+            }
+            else
+            {
+                userMode = -1;  // wanted mode not supported, search for best mode
+            }
+        }
+        else
+        {
+            userMode = -1;      // wanted mode not supported, search for best mode
+        }
+
+        //if userMode is available: set it and update size
+        if (userMode != -1)
+        {
+            code = dc1394_video_set_mode(dcCam, wantedMode);
+            uint32_t width, height;
+            dc1394_get_image_size_from_video_mode(dcCam, wantedMode, &width, &height);
+            frameWidth  = (int)width;
+            frameHeight = (int)height;
+        }
+    }
+    //GH <---
+
+    // search for best mode
     if (userMode == -1 && (frameWidth > 0 || frameHeight > 0))
     {
         dc1394video_mode_t bestMode = (dc1394video_mode_t) - 1;
@@ -311,8 +367,8 @@
         for (i = 0; i < (int)videoModes.num; i++)
         {
             dc1394video_mode_t mode = videoModes.modes[i];
-			if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX)
-				continue;
+            if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX)
+                continue;
             int pref = -1;
             dc1394color_coding_t colorCoding;
             dc1394_get_color_coding_from_video_mode(dcCam, mode, &colorCoding);
@@ -348,16 +404,6 @@
             code = dc1394_video_set_mode(dcCam, bestMode);
     }
     
-    if (userMode > 0)
-    {
-        dc1394video_modes_t videoModes;
-        dc1394_video_get_supported_modes(dcCam, &videoModes);
-        if (userMode < (int)videoModes.num)
-        {
-            dc1394video_mode_t mode = videoModes.modes[userMode];
-            code = dc1394_video_set_mode(dcCam, mode);
-        }
-    }
 
     if (fps > 0)
     {
@@ -619,13 +665,33 @@
                                                   &feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS)
         return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value;
         break;
+    //GH --->
+    case CV_CAP_PROP_GUID:
+        //the least 32 bits are enough to identify the camera
+        return (double) (guid & 0x00000000FFFFFFFF);
+        break;
+    case CV_CAP_PROP_MODE:
+        return (double) userMode;
+        break;
+    case CV_CAP_PROP_ISO_SPEED:
+        return (double) isoSpeed;
+
     default:
-        if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
-            && dcCam)
-            //&& feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable)
-            if (dc1394_feature_get_value(dcCam,(dc1394feature_t)dc1394properties[propId],
-                &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value) == DC1394_SUCCESS)
-              return feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value;
+        if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1 && dcCam)
+
+          //check read-capable
+          if (feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].readout_capable)
+          {
+            if (dc1394_feature_get_value(
+                                           dcCam,
+                                           (dc1394feature_t)dc1394properties[propId],
+                                           &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value
+                                         )
+                   == DC1394_SUCCESS
+                 )
+             return feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value;
+          }
+    //GH <---
     }
     return -1; // the value of the feature can be 0, so returning 0 as an error is wrong
 }
@@ -648,98 +714,127 @@
         break;
     case CV_CAP_PROP_FPS:
     	if(started)
-			return false;
-        fps = value;
-        break;
+			  return false;
+      fps = value;
+      break;
     case CV_CAP_PROP_RECTIFICATION:
         if( cameraId != VIDERE )
             return false;
         rectify = fabs(value) > FLT_EPSILON;
         break;
     case CV_CAP_PROP_MODE:
+        if(started)
+          return false;
         userMode = cvRound(value);
+        break;
+    case CV_CAP_PROP_ISO_SPEED:
+        if(started)
+          return false;
+        isoSpeed = cvRound(value);
         break;
         //The code below is based on coriander, callbacks.c:795, refer to case RANGE_MENU_MAN :
          default:
-             if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1
-                 && dcCam)
+
+           //GH --->
+             if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1 && dcCam)
              {
+                 //get the corresponding feature from property-id
+                 dc1394feature_info_t *act_feature = &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN];
+
                  if (cvRound(value) == CV_CAP_PROP_DC1394_OFF)
                  {
-                     if ((feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable)
-                         && (dc1394_feature_set_power(dcCam, (dc1394feature_t)dc1394properties[propId], DC1394_OFF)==DC1394_SUCCESS))
+                     if (  (act_feature->on_off_capable)
+                           && (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_OFF) == DC1394_SUCCESS))
                      {
-                         feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on=DC1394_OFF;
+                         act_feature->is_on=DC1394_OFF;
                          return true;
                      }
                      return false;
                  }
+
                  //try to turn the feature ON, feature can be ON and at the same time it can be not capable to change state to OFF
-                 if ( feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on == DC1394_OFF &&
-                      (feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable == DC1394_TRUE))
+                 if ( (act_feature->is_on == DC1394_OFF) && (act_feature->on_off_capable == DC1394_TRUE))
                  {
-                     if (dc1394_feature_set_power(dcCam, (dc1394feature_t)dc1394properties[propId], DC1394_ON) == DC1394_SUCCESS)
-                       feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on=DC1394_ON;
+                     if (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_ON) == DC1394_SUCCESS)
+                       act_feature->is_on=DC1394_ON;
                  }
+
                  //turn off absolute mode - the actual value will be stored in the value field,
                  //otherwise it would be stored into CSR (control and status register) absolute value
-                 if (feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].absolute_capable
-                     && dc1394_feature_set_absolute_control(dcCam, (dc1394feature_t)dc1394properties[propId], DC1394_OFF) !=DC1394_SUCCESS)
+                 if (act_feature->absolute_capable
+                     && dc1394_feature_set_absolute_control(dcCam, act_feature->id, DC1394_OFF) !=DC1394_SUCCESS)
                      return false;
                  else
-                     feature_set.feature[(dc1394feature_t)dc1394properties[propId]-DC1394_FEATURE_MIN].abs_control=DC1394_OFF;
+                     act_feature->abs_control=DC1394_OFF;
+
                  //set AUTO
                  if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_AUTO)
                  {
-                     if (dc1394_feature_set_mode(dcCam, (dc1394feature_t)dc1394properties[propId], DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS)
+                     if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS)
                          return false;
-                     feature_set.feature[(dc1394feature_t)dc1394properties[propId]-DC1394_FEATURE_MIN].current_mode=DC1394_FEATURE_MODE_AUTO;
+                     act_feature->current_mode=DC1394_FEATURE_MODE_AUTO;
                      return true;
                  }
+
                  //set ONE PUSH
                  if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO)
                  {
                      //have to set to manual first, otherwise one push will be ignored (AVT  manual 4.3.0 p. 115)
-                     if (dc1394_feature_set_mode(dcCam, (dc1394feature_t)dc1394properties[propId], DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS)
+                     if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS)
                          return false;
                      //will change to
-                     feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].current_mode=DC1394_FEATURE_MODE_ONE_PUSH_AUTO;
+                     act_feature->current_mode=DC1394_FEATURE_MODE_ONE_PUSH_AUTO;
                      return true;
                  }
+
                  //set the feature to MANUAL mode,
-                 if (dc1394_feature_set_mode(dcCam, (dc1394feature_t)dc1394properties[propId], DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS)
+                 if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS)
                      return false;
                  else
-                     feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].current_mode=DC1394_FEATURE_MODE_MANUAL;
+                   act_feature->current_mode=DC1394_FEATURE_MODE_MANUAL;
+
                  // if property is one of the white balance features treat it in different way
                  if (propId == CV_CAP_PROP_WHITE_BALANCE_BLUE_U)
                  {
-                     if (dc1394_feature_whitebalance_set_value(dcCam,cvRound(value), feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].RV_value)!=DC1394_SUCCESS)
+                     if (dc1394_feature_whitebalance_set_value(dcCam,cvRound(value), act_feature->RV_value)!=DC1394_SUCCESS)
                          return false;
                      else
                      {
-                         feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value = cvRound(value);
+                         act_feature->BU_value = cvRound(value);
                          return true;
                      }
                  }
                  if (propId == CV_CAP_PROP_WHITE_BALANCE_RED_V)
                  {
-                     if (dc1394_feature_whitebalance_set_value(dcCam,feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].BU_value,cvRound(value))!=DC1394_SUCCESS)
+                     if (dc1394_feature_whitebalance_set_value(dcCam,act_feature->BU_value,cvRound(value))!=DC1394_SUCCESS)
                          return false;
                      else
                      {
-                         feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value = cvRound(value);
+                         act_feature->RV_value = cvRound(value);
                          return true;
                      }
                  }
+
                  // finally set the feature
-                 if (dc1394_feature_set_value(dcCam,(dc1394feature_t)dc1394properties[propId],cvRound(value)) == DC1394_SUCCESS)
+
+                 //first: check boundaries
+                 if (value < act_feature->min)
                  {
-                     feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value = value;
+                   value = act_feature->min;
+                 }
+                 else if (value > act_feature->max)
+                 {
+                   value = act_feature->max;
+                 }
+
+                 if (dc1394_feature_set_value(dcCam,act_feature->id,cvRound(value)) == DC1394_SUCCESS)
+                 {
+                     act_feature->value = value;
                      return true;
                  }
              }
              return false;
+
     }
     return true;
 }
