1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CORE__GLTF__GLTF2_UTIL_H
17 #define CORE__GLTF__GLTF2_UTIL_H
18 
19 #include <base/containers/string.h>
20 #include <base/containers/string_view.h>
21 #include <base/containers/vector.h>
22 #include <core/namespace.h>
23 
24 #include "gltf/data.h"
25 
CORE3D_BEGIN_NAMESPACE()26 CORE3D_BEGIN_NAMESPACE()
27 namespace GLTF2 {
28 // Helper functions to access GLTF2 data.
29 bool GetAttributeType(BASE_NS::string_view dataType, AttributeBase& out);
30 bool GetMimeType(BASE_NS::string_view type, MimeType& out);
31 
32 bool GetDataType(BASE_NS::string_view dataType, DataType& out);
33 bool GetCameraType(BASE_NS::string_view type, CameraType& out);
34 
35 bool GetAlphaMode(BASE_NS::string_view dataType, AlphaMode& out);
36 bool GetBlendMode(BASE_NS::string_view dataType, BlendMode& out);
37 
38 bool GetAnimationInterpolation(BASE_NS::string_view interpolation, AnimationInterpolation& out);
39 bool GetAnimationPath(BASE_NS::string_view path, AnimationPath& out);
40 
41 BASE_NS::string_view GetAttributeType(AttributeBase type);
42 BASE_NS::string_view GetMimeType(MimeType type);
43 BASE_NS::string_view GetDataType(DataType type);
44 BASE_NS::string_view GetCameraType(CameraType type);
45 
46 #if defined(GLTF2_EXTENSION_KHR_LIGHTS) || defined(GLTF2_EXTENSION_KHR_LIGHTS_PBR)
47 bool GetLightType(BASE_NS::string_view type, LightType& out);
48 BASE_NS::string_view GetLightType(LightType type);
49 #endif
50 
51 BASE_NS::string_view GetAlphaMode(AlphaMode mode);
52 BASE_NS::string_view GetBlendMode(BlendMode mode);
53 BASE_NS::string_view GetAnimationInterpolation(AnimationInterpolation interpolation);
54 BASE_NS::string_view GetAnimationPath(AnimationPath path);
55 
56 uint32_t GetComponentByteSize(ComponentType component);
57 uint32_t GetComponentsCount(DataType type);
58 ComponentType GetAlternativeType(ComponentType component, size_t newByteCount);
59 
60 #if defined(GLTF2_EXTENSION_KHR_MESH_QUANTIZATION)
61 BASE_NS::string_view ValidatePrimitiveAttributeQuatization(
62     AttributeType attribute, DataType accessorType, ComponentType accessorComponentType);
63 BASE_NS::string_view ValidateMorphTargetAttributeQuantization(
64     AttributeType attribute, DataType accessorType, ComponentType accessorComponentType);
65 #endif
66 BASE_NS::string_view ValidatePrimitiveAttribute(
67     AttributeType attribute, DataType accessorType, ComponentType accessorComponentType);
68 BASE_NS::string_view ValidateMorphTargetAttribute(
69     AttributeType attribute, DataType accessorType, ComponentType accessorComponentType);
70 
71 void SplitFilename(BASE_NS::string_view source, BASE_NS::string_view& base, BASE_NS::string_view& path);
72 void SplitBaseFilename(BASE_NS::string_view source, BASE_NS::string_view& name, BASE_NS::string_view& extension);
73 
74 BASE_NS::string_view ParseDataUri(const BASE_NS::string_view in, size_t& offsetToData);
75 bool DecodeDataURI(BASE_NS::vector<uint8_t>& out, BASE_NS::string_view in, size_t reqBytes, bool checkSize,
76     BASE_NS::string_view& mimeType);
77 bool IsDataURI(BASE_NS::string_view in);
78 
79 // Buffer / data helpers
80 struct GLTFLoadDataResult {
81     GLTFLoadDataResult() = default;
82     GLTFLoadDataResult(const GLTFLoadDataResult& other) = delete;
83     GLTFLoadDataResult(GLTFLoadDataResult&& other) noexcept;
84 
85     GLTFLoadDataResult& operator=(GLTFLoadDataResult&& other) noexcept;
86 
87     bool success { false };
88     bool normalized { false };
89     BASE_NS::string error;
90 
91     ComponentType componentType;
92     size_t componentByteSize { 0 };
93     size_t componentCount { 0 };
94 
95     size_t elementSize { 0 };
96     size_t elementCount { 0 };
97 
98     BASE_NS::vector<float> min;
99     BASE_NS::vector<float> max;
100 
101     BASE_NS::vector<uint8_t> data;
102 };
103 
104 struct BufferLoadResult {
105     bool success { true };
106     BASE_NS::string error;
107 };
108 
109 // Populate GLTF buffers with data.
110 BufferLoadResult LoadBuffers(const Data& data, CORE_NS::IFileManager& fileManager);
111 
112 enum UriLoadResult {
113     URI_LOAD_SUCCESS,
114     URI_LOAD_FAILED_INVALID_MIME_TYPE,
115     URI_LOAD_FAILED_TO_DECODE_BASE64,
116     URI_LOAD_FAILED_TO_READ_FILE
117 };
118 
119 /** Load URI to data buffer.
120  * @param aUri Uri to data, this can point either to data uri or external file.
121  * @param mimeType Requested mime type, such as "image", can be empty to allow all mime types.
122  * @param aFilePath Root path that can be used for relative uri/file lookup.
123  * @param aFileManager File manager to access external files.
124  * @param aOutExtension File extension of the actual file.
125  * @param aOutData Output data.
126  * @return Loading result, URI_LOAD_SUCCESS if data was successfully loaded.
127  */
128 UriLoadResult LoadUri(BASE_NS::string_view uri, BASE_NS::string_view mimeType, BASE_NS::string_view filepath,
129     CORE_NS::IFileManager& fileManager, BASE_NS::string_view& outExtension, BASE_NS::vector<uint8_t>& outData);
130 
131 // Load accessor data.
132 GLTFLoadDataResult LoadData(Accessor const& accessor);
133 } // namespace GLTF2
134 CORE3D_END_NAMESPACE()
135 
136 #endif // CORE__GLTF__GLTF2_UTIL_H
137