[libcamera-devel] [PATCH v2] cam: capture_script: Add support for Rectangle and Size controls

Paul Elder paul.elder at ideasonboard.com
Thu Jul 28 09:23:11 CEST 2022


Add support for Rectangle and Size control values in the capture script
parser.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>

---
Changes in v2:
- fix compilation error for the Size parser
---
 src/cam/capture_script.cpp | 61 +++++++++++++++++++++++++++++++++++---
 src/cam/capture_script.h   |  4 +++
 2 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/src/cam/capture_script.cpp b/src/cam/capture_script.cpp
index 9f22d5f7..07b14613 100644
--- a/src/cam/capture_script.cpp
+++ b/src/cam/capture_script.cpp
@@ -252,6 +252,53 @@ std::string CaptureScript::parseScalar()
 	return eventScalarValue(event);
 }
 
+Rectangle CaptureScript::unpackRectangle(const ControlId *id,
+					 const std::string &repr)
+{
+	/* Format: (<left>,<top>)/<width>x<height> */
+
+	std::map<char, int> delims = { { '(', -1 },
+				       { ')', -1 },
+				       { ',', -1 },
+				       { '/', -1 },
+				       { 'x', -1 } };
+
+	for (unsigned int i = 0; i < repr.size(); i++)
+		if (delims.count(repr[i]))
+			delims[repr[i]] = i;
+
+	for (auto &pair : delims) {
+		if (pair.second == -1) {
+			unpackFailure(id, repr);
+			return Rectangle{};
+		}
+	}
+
+	int32_t left =   strtol(repr.substr(delims['('] + 1, delims[',']).c_str(), NULL, 10);
+	int32_t top =    strtol(repr.substr(delims[','] + 1, delims[')']).c_str(), NULL, 10);
+	int32_t width =  strtol(repr.substr(delims['/'] + 1, delims['x']).c_str(), NULL, 10);
+	int32_t height = strtol(repr.substr(delims['x'] + 1).c_str(), NULL, 10);
+
+	return Rectangle(left, top, width, height);
+}
+
+Size CaptureScript::unpackSize(const ControlId *id,
+			       const std::string &repr)
+{
+	/* Format: <width>x<height> */
+
+	unsigned int pos = repr.find("x");
+	if (pos == std::string::npos) {
+		unpackFailure(id, repr);
+		return Size{};
+	}
+
+	int32_t width = strtol(repr.substr(0, pos).c_str(), NULL, 10);
+	int32_t height = strtol(repr.substr(pos).c_str(), NULL, 10);
+
+	return Size(width, height);
+}
+
 void CaptureScript::unpackFailure(const ControlId *id, const std::string &repr)
 {
 	static const std::map<unsigned int, const char *> typeNames = {
@@ -281,6 +328,8 @@ ControlValue CaptureScript::unpackControl(const ControlId *id,
 					  const std::string &repr)
 {
 	ControlValue value{};
+	Rectangle rect;
+	Size size;
 
 	switch (id->type()) {
 	case ControlTypeNone:
@@ -324,13 +373,17 @@ ControlValue CaptureScript::unpackControl(const ControlId *id,
 		value.set<std::string>(repr);
 		break;
 	}
-	case ControlTypeRectangle:
-		/* \todo Parse rectangles. */
+	case ControlTypeRectangle: {
+		rect = unpackRectangle(id, repr);
+		value.set<Rectangle>(rect);
 		break;
-	case ControlTypeSize:
-		/* \todo Parse Sizes. */
+	}
+	case ControlTypeSize: {
+		size = unpackSize(id, repr);
+		value.set<Size>(size);
 		break;
 	}
+	}
 
 	return value;
 }
diff --git a/src/cam/capture_script.h b/src/cam/capture_script.h
index 8b4f8f62..f2dbfdf8 100644
--- a/src/cam/capture_script.h
+++ b/src/cam/capture_script.h
@@ -55,6 +55,10 @@ private:
 
 	std::string parseScalar();
 
+	libcamera::Rectangle unpackRectangle(const libcamera::ControlId *id,
+					     const std::string &repr);
+	libcamera::Size unpackSize(const libcamera::ControlId *id,
+				   const std::string &repr);
 	void unpackFailure(const libcamera::ControlId *id,
 			   const std::string &repr);
 	libcamera::ControlValue unpackControl(const libcamera::ControlId *id,
-- 
2.30.2



More information about the libcamera-devel mailing list