From 9c79be7555764bce3611f3e971b03b1d2359e980 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Wed, 1 Sep 2021 11:40:45 +0200
Subject: [PATCH] Implement Image code generation

---
 .../cpp/serializer/ndarray/Image.cpp          | 155 ++++++++++++------
 1 file changed, 107 insertions(+), 48 deletions(-)

diff --git a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Image.cpp b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Image.cpp
index 4dfa32d98..2f80ec2f1 100644
--- a/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Image.cpp
+++ b/source/RobotAPI/libraries/aron/core/codegenerator/codeWriter/cpp/serializer/ndarray/Image.cpp
@@ -52,7 +52,7 @@ namespace armarx::aron::cppserializer::serializer
 
     CppBlockPtr ImageSerializer::getResetHardBlock(const std::string& accessor) const
     {
-        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
 
         std::string typeConstant;
         {
@@ -76,7 +76,7 @@ namespace armarx::aron::cppserializer::serializer
 
     CppBlockPtr ImageSerializer::getResetSoftBlock(const std::string& accessor) const
     {
-        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
 
         block_if_data->addLine(accessor + " = 0;");
 
@@ -86,7 +86,7 @@ namespace armarx::aron::cppserializer::serializer
 
     CppBlockPtr ImageSerializer::getWriteTypeBlock(const std::string& accessor) const
     {
-        CppBlockPtr b = CppBlockPtr(new CppBlock());
+        CppBlockPtr b = std::make_shared<CppBlock>();
 
         std::string typeName;
         switch (typenavigator->getPixelType())
@@ -96,107 +96,166 @@ case typeConstant : \
     typeName = "aron::typenavigator::ImageNavigator::pixelTypeToName( " #typeConstant " )"; \
     break;
 
-                CASE(aron::typenavigator::ImagePixelType::RGB24)
-                CASE(aron::typenavigator::ImagePixelType::DEPTH32)
+                CASE(::armarx::aron::typenavigator::ImagePixelType::RGB24)
+                CASE(::armarx::aron::typenavigator::ImagePixelType::DEPTH32)
 
 #undef CASE
         }
 
-        b->addLine("w.writeImage({\"" + typeName + "\", " + MAYBE_TO_STRING(typenavigator->getMaybe()) + "});  // of " + accessor);
+        b->addLine("w.writeImage({" + typeName + ", " + MAYBE_TO_STRING(typenavigator->getMaybe()) + "});  // of " + accessor);
         return b;
     }
 
 
     CppBlockPtr ImageSerializer::getWriteBlock(const std::string& accessor) const
     {
-        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        CppBlockPtr block = std::make_shared<CppBlock>();
 
         std::string escaped_accessor = EscapeAccessor(accessor);
         std::string accessor_shape = "shape";
 
-        block_if_data->addLine("std::vector<int> " + accessor_shape + "(" + accessor + ".size.p, " + accessor + ".size.p + " + accessor + ".dims);");
-        block_if_data->addLine(accessor_shape + ".push_back(" + accessor + nextEl() + "elemSize());");
+        block->addLine("std::vector<int> " + accessor_shape + "(" + accessor + ".size.p, " + accessor + ".size.p + " + accessor + ".dims);");
+        block->addLine(accessor_shape + ".push_back(" + accessor + nextEl() + "elemSize());");
 
 
-#if 0
+#if 0  // Target code:
         std::string type;
-        switch (the_depth_32_image.type())
+        switch (the_depth32_image.type())
         {
             case CV_8UC3:
-                type = aron::typenavigator::ImageNavigator::pixelTypeToName(aron::typenavigator::ImagePixelType::RGB24);
+                type = ::armarx::aron::typenavigator::ImageNavigator::pixelTypeToName(::armarx::aron::typenavigator::ImagePixelType::RGB24);
                 break;
             case CV_32FC1:
-                type = aron::typenavigator::ImageNavigator::pixelTypeToName(aron::typenavigator::ImagePixelType::DEPTH32);
+                type = ::armarx::aron::typenavigator::ImageNavigator::pixelTypeToName(::armarx::aron::typenavigator::ImagePixelType::DEPTH32);
                 break;
             default:
             {
                 std::stringstream ss;
-                ss << "OpenCV image type " << the_depth_32_image.type() << " cannot be serialized.";
-                throw aron::error::AronException("ImageTest", __FUNCTION__, ss.str());
+                ss << "OpenCV image type " << the_depth32_image.type() << " cannot be serialized.";
+                throw ::armarx::aron::error::AronException("ImageTest", __FUNCTION__, ss.str());
             }
         }
 #endif
 
-        block_if_data->addLine("std::string type;");
+        block->addLine("std::string arrayType;");
+        block->addLine("switch (" + accessor + ".type())");
         {
-            CppBlockPtr block_wrap_switch = std::make_shared<CppBlock>();
-            block_wrap_switch->addLine("switch (" + accessor + ".type())");
-            {
-                CppBlockPtr block_switch = std::make_shared<CppBlock>();
+            CppBlockPtr block_switch = std::make_shared<CppBlock>();
 
-#define ADD_CASE( typeConstant ) \
+#define CASE( typeConstant ) \
     block_switch->addLine("case " + pixelTypeMap.at(typeConstant) + ":"); \
-    block_switch->addLine("type = aron::typenavigator::ImageNavigator::pixelTypeToName(" #typeConstant ");")
+    block_switch->addLine("arrayType = ::armarx::aron::typenavigator::ImageNavigator::pixelTypeToName(" #typeConstant ");"); \
+    block_switch->addLine("break;")
 
-                ADD_CASE(aron::typenavigator::ImagePixelType::RGB24);
-                ADD_CASE(aron::typenavigator::ImagePixelType::DEPTH32);
+            CASE(::armarx::aron::typenavigator::ImagePixelType::RGB24);
+            CASE(::armarx::aron::typenavigator::ImagePixelType::DEPTH32);
 
-#undef ADD_CASE
-
-                block_switch->addLine("default:");
-                {
-                    CppBlockPtr block_default = std::make_shared<CppBlock>();
-                    block_default->addLine("std::stringstream ss;");
-                    block_default->addLine("ss << \"OpenCV image type \" << " + accessor + ".type() << \" cannot be serialized.\";");
-                    block_default->addLine("throw aron::error::AronException(\"" + typenavigator->getName() + "\", __FUNCTION__, ss.str());");
+#undef CASE
 
-                    block_switch->addBlock(block_default);
-                }
+            block_switch->addLine("default:");
+            {
+                CppBlockPtr block_default = std::make_shared<CppBlock>();
+                block_default->addLine("std::stringstream ss;");
+                block_default->addLine("ss << \"OpenCV image type \" << " + accessor + ".type() << \" cannot be serialized.\";");
+                block_default->addLine("throw ::armarx::aron::error::AronException(\"" + typenavigator->getName() + "\", __FUNCTION__, ss.str());");
 
-                block_wrap_switch->addBlock(block_switch);
+                block_switch->addBlock(block_default);
             }
-            block_if_data->addBlock(block_wrap_switch);
+            block->addBlock(block_switch);
         }
 
 
-        block_if_data->addLine("w.writeNDArray(" + accessor_shape + ", std::to_string(" + accessor + nextEl() + "type()), reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "data)); // of " + accessor);
+        block->addLine("w.writeNDArray(" + accessor_shape + ", arrayType, reinterpret_cast<const unsigned char*>(" + accessor + nextEl() + "data)); // of " + accessor);
 
-        return ResolveMaybeWriteBlock(accessor, block_if_data, typenavigator);
+        return ResolveMaybeWriteBlock(accessor, block, typenavigator);
     }
 
 
     CppBlockPtr ImageSerializer::getReadBlock(const std::string& accessor) const
     {
-        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
-        std::string escaped_accessor = EscapeAccessor(accessor);
-        std::string read_start_result_accessor = escaped_accessor + READ_START_RETURN_TYPE_ACCESSOR;
+        const std::string escaped_accessor = EscapeAccessor(accessor);
+        const std::string read_start_result_accessor = escaped_accessor + READ_START_RETURN_TYPE_ACCESSOR;
+
+#if 0   // Target code
+        auto the_rgb24_image_return_type = r.readStartNDArray(); // of the_rgb24_image
+
+        if (!the_rgb24_image_return_type.dims.empty())
+        {
+            std::vector<int> shape{the_rgb24_image_return_type.dims.begin(), std::prev(the_rgb24_image_return_type.dims.end())};
 
-        block_if_data->addLine("if (!" + read_start_result_accessor + ".dims.empty())");
-        CppBlockPtr b2 = CppBlockPtr(new CppBlock());
-        b2->addLine(accessor + " = " + getCoreCppTypename() + "(std::vector<int>({" + read_start_result_accessor + ".dims.begin(), std::prev(" + read_start_result_accessor + ".dims.end())}), std::stoi(" + read_start_result_accessor + ".type));");
-        b2->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data)); // of " + accessor);
-        block_if_data->addBlock(b2);
+            ::armarx::aron::typenavigator::ImagePixelType pixelType = ::armarx::aron::typenavigator::ImageNavigator::pixelTypeFromName(the_rgb24_image_return_type.type);
+            int cvMatType = 0;
+            switch (pixelType)
+            {
+                case ::armarx::aron::typenavigator::ImagePixelType::RGB24:
+                    cvMatType =  CV_8UC3;
+                case ::armarx::aron::typenavigator::ImagePixelType::DEPTH32:
+                    cvMatType =  CV_32FC1;
+                default:
+                {
+                    std::stringstream ss;
+                    ss << "NDArray Type '" << the_rgb24_image_return_type.type << "' cannot be deserialized as image.";
+                    throw ::armarx::aron::error::AronException("AronImageType", __FUNCTION__, ss.str());
+                }
+            }
+
+            the_rgb24_image.create(shape, cvMatType);
+            r.readEndNDArray(reinterpret_cast<unsigned char*>(the_rgb24_image.data)); // of the_rgb24_image
+        }
+#endif
 
-        return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block_if_data, typenavigator, true);
+        CppBlockPtr block = std::make_shared<CppBlock>();
+
+        block->addLine("if (!" + read_start_result_accessor + ".dims.empty())");
+        {
+            CppBlockPtr block_if = std::make_shared<CppBlock>();
+
+            block_if->addLine("std::vector<int> shape{" + read_start_result_accessor + ".dims.begin(), std::prev(" + read_start_result_accessor + ".dims.end())};");
+
+            block_if->addLine("aron::typenavigator::ImagePixelType pixelType = ::armarx::aron::typenavigator::ImageNavigator::pixelTypeFromName(" + read_start_result_accessor + ".type);");
+            block_if->addLine("int cvMatType = 0;");
+            block_if->addLine("switch (pixelType)");
+            {
+                CppBlockPtr block_switch = std::make_shared<CppBlock>();
+
+    #define CASE( typeConstant ) \
+        block_switch->addLine("case " #typeConstant ":"); \
+        block_switch->addLine("cvMatType = " + pixelTypeMap.at(typeConstant) + ";"); \
+        block_switch->addLine("break;")
+
+                CASE(::armarx::aron::typenavigator::ImagePixelType::RGB24);
+                CASE(::armarx::aron::typenavigator::ImagePixelType::DEPTH32);
+
+    #undef CASE
+
+                block_switch->addLine("default:");
+                {
+                    CppBlockPtr block_default = std::make_shared<CppBlock>();
+                    block_default->addLine("std::stringstream ss;");
+                    block_default->addLine("ss << \"NdArray Type '\" << " + read_start_result_accessor + ".type << \"' cannot be deserialized as image.\";");
+                    block_default->addLine("throw ::armarx::aron::error::AronException(\"AronImageType\", __FUNCTION__, ss.str());");
+
+                    block_switch->addBlock(block_default);
+                }
+                block_if->addBlock(block_switch);
+            }
+
+            block_if->addLine(accessor + ".create(shape, cvMatType);");
+            block_if->addLine("r.readEndNDArray(reinterpret_cast<unsigned char*>(" + accessor + nextEl() + "data)); // of " + accessor);
+            block->addBlock(block_if);
+        }
+
+        return ResolveMaybeReadBlock(accessor, "r.readStartNDArray()", block, typenavigator, true);
     }
 
 
     CppBlockPtr ImageSerializer::getEqualsBlock(const std::string& accessor, const std::string& otherInstanceAccessor) const
     {
-        CppBlockPtr block_if_data = CppBlockPtr(new CppBlock());
+        CppBlockPtr block_if_data = std::make_shared<CppBlock>();
         block_if_data->addLine("if (cv::countNonZero(" + accessor + " != " + otherInstanceAccessor + ") != 0)");
         block_if_data->addLineAsBlock("return false;");
         return ResolveMaybeEqualsBlock(accessor, otherInstanceAccessor, block_if_data, typenavigator);
     }
 }
 
+
-- 
GitLab