+/*\r
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+// INTERNAL INCLUDES\r
+#include <dali-scene3d/internal/loader/gltf2-asset.h>\r
+#include <dali-scene3d/internal/loader/json-reader.h>\r
+#include <dali-scene3d/public-api/loader/load-scene-metadata.h>\r
+#include <dali-scene3d/public-api/loader/utils.h>\r
+\r
+namespace js = json;\r
+namespace gt = gltf2;\r
+\r
+namespace Dali::Scene3D::Loader\r
+{\r
+namespace\r
+{\r
+struct ImageData\r
+{\r
+ struct SamplingMode\r
+ {\r
+ enum Type\r
+ {\r
+ INVALID = -1,\r
+ BOX = Dali::SamplingMode::BOX,\r
+ NEAREST = Dali::SamplingMode::NEAREST,\r
+ LINEAR = Dali::SamplingMode::LINEAR,\r
+ BOX_THEN_NEAREST = Dali::SamplingMode::BOX_THEN_NEAREST,\r
+ BOX_THEN_LINEAR = Dali::SamplingMode::BOX_THEN_LINEAR,\r
+ NO_FILTER = Dali::SamplingMode::NO_FILTER,\r
+ DONT_CARE = Dali::SamplingMode::DONT_CARE\r
+ };\r
+\r
+ static Type FromString(const char* s, size_t len);\r
+ };\r
+\r
+ std::string mImageUri{}; ///< The URI of the image\r
+ uint16_t mMinWidth{}; ///< The minimum width of the image\r
+ uint16_t mMinHeight{}; ///< The mimimum height of the image\r
+\r
+ ImageData::SamplingMode::Type mSamplingMode{ImageData::SamplingMode::BOX_THEN_LINEAR}; ///< The sampling mode used to resize the image.\r
+};\r
+\r
+const std::map<std::string_view, ImageData::SamplingMode::Type> SAMPLING_MODE_TYPES{\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, BOX),\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, NEAREST),\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, LINEAR),\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, BOX_THEN_NEAREST),\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, BOX_THEN_LINEAR),\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, NO_FILTER),\r
+ ENUM_STRING_MAPPING(ImageData::SamplingMode, DONT_CARE),\r
+};\r
+\r
+ENUM_TYPE_FROM_STRING(ImageData::SamplingMode, SAMPLING_MODE_TYPES)\r
+\r
+struct MetaData\r
+{\r
+ std::vector<ImageData> mImageData;\r
+};\r
+\r
+const auto IMAGE_METADATA_READER = std::move(js::Reader<ImageData>()\r
+ .Register(*js::MakeProperty("uri", js::Read::String, &ImageData::mImageUri))\r
+ .Register(*js::MakeProperty("minWidth", js::Read::Number, &ImageData::mMinWidth))\r
+ .Register(*js::MakeProperty("minHeight", js::Read::Number, &ImageData::mMinHeight))\r
+ .Register(*js::MakeProperty("samplingMode", gt::ReadStringEnum<ImageData::SamplingMode>, &ImageData::mSamplingMode)));\r
+\r
+const auto METADATA_READER = std::move(js::Reader<MetaData>()\r
+ .Register(*js::MakeProperty("images", js::Read::Array<ImageData, js::ObjectReader<ImageData>::Read>, &MetaData::mImageData)));\r
+\r
+} // namespace\r
+\r
+void LoadSceneMetadata(const std::string& url, SceneMetadata& sceneMetadata)\r
+{\r
+ bool failed = false;\r
+ auto js = LoadTextFile(url.c_str(), &failed);\r
+ if(failed)\r
+ {\r
+ return;\r
+ }\r
+\r
+ json::unique_ptr root(json_parse(js.c_str(), js.size()));\r
+ if(!root)\r
+ {\r
+ throw std::runtime_error("Failed to parse " + url);\r
+ }\r
+ auto& rootObj = js::Cast<json_object_s>(*root);\r
+\r
+ static bool setObjectReaders = true;\r
+ if(setObjectReaders)\r
+ {\r
+ js::SetObjectReader(IMAGE_METADATA_READER);\r
+\r
+ setObjectReaders = false;\r
+ }\r
+\r
+ MetaData metaData;\r
+ METADATA_READER.Read(rootObj, metaData);\r
+\r
+ sceneMetadata.mImageMetadata.reserve(metaData.mImageData.size() + metaData.mImageData.size());\r
+ for(auto&& data : metaData.mImageData)\r
+ {\r
+ if(data.mSamplingMode == ImageData::SamplingMode::INVALID)\r
+ {\r
+ throw std::runtime_error("Sampling mode type unsupported.");\r
+ }\r
+ else\r
+ {\r
+ sceneMetadata.mImageMetadata.insert({data.mImageUri, ImageMetadata{ImageDimensions(data.mMinWidth, data.mMinHeight), static_cast<Dali::SamplingMode::Type>(data.mSamplingMode)}});\r
+ }\r
+ }\r
+}\r
+\r
+} // namespace Dali::Scene3D::Loader\r