From f71c76ceff7ad13490fd77800059ab2bd2a61498 Mon Sep 17 00:00:00 2001 From: Daniel Semkowicz Date: Mon, 27 Jun 2022 14:28:05 +0200 Subject: cam: Add Rectangle type parsing in capture script This change is required for AfWindows control from capture script. Parser expects array of arrays of parameters, so it is possible to specify multiple rectangles. Signed-off-by: Daniel Semkowicz Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder Signed-off-by: Jacopo Mondi --- src/cam/capture_script.cpp | 145 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 134 insertions(+), 11 deletions(-) (limited to 'src/cam/capture_script.cpp') diff --git a/src/cam/capture_script.cpp b/src/cam/capture_script.cpp index 9f22d5f7..a8304433 100644 --- a/src/cam/capture_script.cpp +++ b/src/cam/capture_script.cpp @@ -232,12 +232,15 @@ int CaptureScript::parseControl(EventPtr event, ControlList &controls) return -EINVAL; } - std::string value = parseScalar(); - if (value.empty()) + const ControlId *controlId = it->second; + + ControlValue val = unpackControl(controlId); + if (val.isNone()) { + std::cerr << "Error unpacking control '" << name << "'" + << std::endl; return -EINVAL; + } - const ControlId *controlId = it->second; - ControlValue val = unpackControl(controlId, value); controls.set(controlId->id(), val); return 0; @@ -252,6 +255,104 @@ std::string CaptureScript::parseScalar() return eventScalarValue(event); } +ControlValue CaptureScript::parseRectangles() +{ + std::vector rectangles; + + std::vector> arrays = parseArrays(); + if (arrays.empty()) + return {}; + + for (const std::vector &values : arrays) { + if (values.size() != 4) { + std::cerr << "Error parsing Rectangle: expected " + << "array with 4 parameters" << std::endl; + return {}; + } + + Rectangle rect = unpackRectangle(values); + rectangles.push_back(rect); + } + + ControlValue controlValue; + controlValue.set(Span(rectangles)); + + return controlValue; +} + +std::vector> CaptureScript::parseArrays() +{ + EventPtr event = nextEvent(YAML_SEQUENCE_START_EVENT); + if (!event) + return {}; + + event = nextEvent(); + if (!event) + return {}; + + std::vector> valueArrays; + + /* Parse single array. */ + if (event->type == YAML_SCALAR_EVENT) { + std::string firstValue = eventScalarValue(event); + if (firstValue.empty()) + return {}; + + std::vector remaining = parseSingleArray(); + + std::vector values = { firstValue }; + values.insert(std::end(values), + std::begin(remaining), std::end(remaining)); + valueArrays.push_back(values); + + return valueArrays; + } + + /* Parse array of arrays. */ + while (1) { + switch (event->type) { + case YAML_SEQUENCE_START_EVENT: { + std::vector values = parseSingleArray(); + valueArrays.push_back(values); + break; + } + case YAML_SEQUENCE_END_EVENT: + return valueArrays; + default: + return {}; + } + + event = nextEvent(); + if (!event) + return {}; + } +} + +std::vector CaptureScript::parseSingleArray() +{ + std::vector values; + + while (1) { + EventPtr event = nextEvent(); + if (!event) + return {}; + + switch (event->type) { + case YAML_SCALAR_EVENT: { + std::string value = eventScalarValue(event); + if (value.empty()) + return {}; + values.push_back(value); + break; + } + case YAML_SEQUENCE_END_EVENT: + return values; + default: + return {}; + } + } +} + void CaptureScript::unpackFailure(const ControlId *id, const std::string &repr) { static const std::map typeNames = { @@ -277,9 +378,24 @@ void CaptureScript::unpackFailure(const ControlId *id, const std::string &repr) << typeName << " control " << id->name() << std::endl; } -ControlValue CaptureScript::unpackControl(const ControlId *id, - const std::string &repr) +ControlValue CaptureScript::unpackControl(const ControlId *id) { + /* Parse complex types. */ + switch (id->type()) { + case ControlTypeRectangle: + return parseRectangles(); + case ControlTypeSize: + /* \todo Parse Sizes. */ + return {}; + default: + break; + } + + /* Parse basic types represented by a single scalar. */ + const std::string repr = parseScalar(); + if (repr.empty()) + return {}; + ControlValue value{}; switch (id->type()) { @@ -324,13 +440,20 @@ ControlValue CaptureScript::unpackControl(const ControlId *id, value.set(repr); break; } - case ControlTypeRectangle: - /* \todo Parse rectangles. */ - break; - case ControlTypeSize: - /* \todo Parse Sizes. */ + default: + std::cerr << "Unsupported control type" << std::endl; break; } return value; } + +libcamera::Rectangle CaptureScript::unpackRectangle(const std::vector &strVec) +{ + int x = strtol(strVec[0].c_str(), NULL, 10); + int y = strtol(strVec[1].c_str(), NULL, 10); + unsigned int width = strtoul(strVec[2].c_str(), NULL, 10); + unsigned int height = strtoul(strVec[3].c_str(), NULL, 10); + + return Rectangle(x, y, width, height); +} -- cgit v1.2.1