| 1225 | } |
| 1226 | |
| 1227 | shared_ptr<Assets::AssetData> Assets::loadImage(AssetPath const& path) const { |
| 1228 | validatePath(path, true, true); |
| 1229 | if (!path.directives.empty()) { |
| 1230 | shared_ptr<ImageData> source = |
| 1231 | as<ImageData>(loadAsset(AssetId{AssetType::Image, {path.basePath, path.subPath, {}}})); |
| 1232 | if (!source) |
| 1233 | return {}; |
| 1234 | StringMap<ImageConstPtr> references; |
| 1235 | StringList referencePaths; |
| 1236 | |
| 1237 | for (auto& directives : path.directives.list()) |
| 1238 | directives.loadOperations(); |
| 1239 | |
| 1240 | path.directives.forEach([&](auto const& entry, Directives const&) { |
| 1241 | addImageOperationReferences(entry.operation, referencePaths); |
| 1242 | }); // TODO: This can definitely be better, was changed quickly to support the new Directives. |
| 1243 | |
| 1244 | |
| 1245 | for (auto const& ref : referencePaths) { |
| 1246 | auto components = AssetPath::split(ref); |
| 1247 | validatePath(components, true, false); |
| 1248 | auto refImage = as<ImageData>(loadAsset(AssetId{AssetType::Image, std::move(components)})); |
| 1249 | if (!refImage) |
| 1250 | return {}; |
| 1251 | references[ref] = refImage->image; |
| 1252 | } |
| 1253 | |
| 1254 | return unlockDuring([&]() { |
| 1255 | auto newData = make_shared<ImageData>(); |
| 1256 | Image newImage = *source->image; |
| 1257 | path.directives.forEach([&](Directives::Entry const& entry, Directives const&) { |
| 1258 | if (auto error = entry.operation.ptr<ErrorImageOperation>()) |
| 1259 | if (auto string = error->cause.ptr<std::string>()) |
| 1260 | throw DirectivesException::format("ImageOperation parse error: {}", *string); |
| 1261 | else |
| 1262 | std::rethrow_exception(error->cause.get<std::exception_ptr>()); |
| 1263 | else |
| 1264 | processImageOperation(entry.operation, newImage, [&](String const& ref) { return references.get(ref).get(); }); |
| 1265 | }); |
| 1266 | newData->image = make_shared<Image>(std::move(newImage)); |
| 1267 | return newData; |
| 1268 | }); |
| 1269 | |
| 1270 | } else if (path.subPath) { |
| 1271 | auto imageData = as<ImageData>(loadAsset(AssetId{AssetType::Image, {path.basePath, {}, {}}})); |
| 1272 | if (!imageData) |
| 1273 | return {}; |
| 1274 | |
| 1275 | // Base image must have frames data associated with it. |
| 1276 | if (!imageData->frames) |
| 1277 | throw AssetException::format("No associated frames file found for image '{}' while resolving image frame '{}'", path.basePath, path); |
| 1278 | |
| 1279 | if (auto alias = imageData->frames->aliases.ptr(*path.subPath)) { |
| 1280 | imageData = as<ImageData>(loadAsset(AssetId{AssetType::Image, {path.basePath, *alias, path.directives}})); |
| 1281 | if (!imageData) |
| 1282 | return {}; |
| 1283 | |
| 1284 | auto newData = make_shared<ImageData>(); |
nothing calls this directly
no test coverage detected