From 132be91de41362281c93677c71a9044ce77c50b8 Mon Sep 17 00:00:00 2001 From: Jinny You Date: Wed, 22 Nov 2023 17:47:57 +0900 Subject: [PATCH] lottie/loader: support external image from memeory lottie I've added new parameter, const string& resourcePath, to load external image on lottie. Result load(const char* data, uint32_t size, const string& mimeType, bool copy, const string& resourcePath) Note: tvgLoadModule will have new overrided method `open`, not to effect to other changes except animation. Issue: #1793 --- inc/thorvg.h | 3 ++- src/loaders/external_jpg/tvgJpgLoader.cpp | 2 +- src/loaders/external_jpg/tvgJpgLoader.h | 2 +- src/loaders/external_png/tvgPngLoader.cpp | 2 +- src/loaders/external_png/tvgPngLoader.h | 2 +- src/loaders/external_webp/tvgWebpLoader.cpp | 2 +- src/loaders/external_webp/tvgWebpLoader.h | 2 +- src/loaders/jpg/tvgJpgLoader.cpp | 2 +- src/loaders/jpg/tvgJpgLoader.h | 2 +- src/loaders/lottie/tvgLottieLoader.cpp | 6 +++++- src/loaders/lottie/tvgLottieLoader.h | 2 +- src/loaders/lottie/tvgLottieParser.cpp | 4 ++-- src/loaders/png/tvgPngLoader.cpp | 2 +- src/loaders/png/tvgPngLoader.h | 2 +- src/loaders/svg/tvgSvgLoader.cpp | 2 +- src/loaders/svg/tvgSvgLoader.h | 2 +- src/loaders/tvg/tvgTvgLoader.cpp | 2 +- src/loaders/tvg/tvgTvgLoader.h | 2 +- src/renderer/tvgLoadModule.h | 2 +- src/renderer/tvgLoader.cpp | 4 ++-- src/renderer/tvgLoader.h | 2 +- src/renderer/tvgPicture.cpp | 4 ++-- src/renderer/tvgPicture.h | 4 ++-- 23 files changed, 32 insertions(+), 27 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 7a2e75d9..ac3362dc 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -1236,6 +1236,7 @@ public: * @param[in] size The size in bytes of the memory occupied by the @p data. * @param[in] mimeType Mimetype or extension of data such as "jpg", "jpeg", "lottie", "svg", "svg+xml", "png", etc. In case an empty string or an unknown type is provided, the loaders will be tried one by one. * @param[in] copy If @c true the data are copied into the engine local buffer, otherwise they are not. + * @param[in] resourcePath Directory path to load external images. * * @retval Result::Success When succeed. * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. @@ -1247,7 +1248,7 @@ public: * @note If you are unsure about the MIME type, you can provide an empty value like @c "", and thorvg will attempt to figure it out. * @since 0.5 */ - Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept; + Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false, const std::string& resourcePath = "") noexcept; /** * @brief Resizes the picture content to the given width and height. diff --git a/src/loaders/external_jpg/tvgJpgLoader.cpp b/src/loaders/external_jpg/tvgJpgLoader.cpp index d147e1fc..a73db94f 100644 --- a/src/loaders/external_jpg/tvgJpgLoader.cpp +++ b/src/loaders/external_jpg/tvgJpgLoader.cpp @@ -100,7 +100,7 @@ finalize: } -bool JpgLoader::open(const char* data, uint32_t size, bool copy) +bool JpgLoader::open(const char* data, uint32_t size, bool copy, const string& resourcePath) { clear(); diff --git a/src/loaders/external_jpg/tvgJpgLoader.h b/src/loaders/external_jpg/tvgJpgLoader.h index f9878355..c356ef83 100644 --- a/src/loaders/external_jpg/tvgJpgLoader.h +++ b/src/loaders/external_jpg/tvgJpgLoader.h @@ -36,7 +36,7 @@ public: using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const string& resourcePath) override; bool read() override; bool close() override; diff --git a/src/loaders/external_png/tvgPngLoader.cpp b/src/loaders/external_png/tvgPngLoader.cpp index adf3b6e0..2694add0 100644 --- a/src/loaders/external_png/tvgPngLoader.cpp +++ b/src/loaders/external_png/tvgPngLoader.cpp @@ -60,7 +60,7 @@ bool PngLoader::open(const string& path) return true; } -bool PngLoader::open(const char* data, uint32_t size, bool copy) +bool PngLoader::open(const char* data, uint32_t size, bool copy, const string& resourcePath) { image->opaque = NULL; diff --git a/src/loaders/external_png/tvgPngLoader.h b/src/loaders/external_png/tvgPngLoader.h index 7d3f7c7c..f6fa8218 100644 --- a/src/loaders/external_png/tvgPngLoader.h +++ b/src/loaders/external_png/tvgPngLoader.h @@ -34,7 +34,7 @@ public: using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const string& resourcePath) override; bool read() override; bool close() override; diff --git a/src/loaders/external_webp/tvgWebpLoader.cpp b/src/loaders/external_webp/tvgWebpLoader.cpp index cbb88932..6c051be9 100644 --- a/src/loaders/external_webp/tvgWebpLoader.cpp +++ b/src/loaders/external_webp/tvgWebpLoader.cpp @@ -107,7 +107,7 @@ finalize: } -bool WebpLoader::open(const char* data, uint32_t size, bool copy) +bool WebpLoader::open(const char* data, uint32_t size, bool copy, const string& resourcePath) { clear(); diff --git a/src/loaders/external_webp/tvgWebpLoader.h b/src/loaders/external_webp/tvgWebpLoader.h index a073ea6c..c97b33f0 100644 --- a/src/loaders/external_webp/tvgWebpLoader.h +++ b/src/loaders/external_webp/tvgWebpLoader.h @@ -34,7 +34,7 @@ public: using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const string& resourcePath) override; bool read() override; bool close() override; diff --git a/src/loaders/jpg/tvgJpgLoader.cpp b/src/loaders/jpg/tvgJpgLoader.cpp index 3bbe5e46..d87a0436 100644 --- a/src/loaders/jpg/tvgJpgLoader.cpp +++ b/src/loaders/jpg/tvgJpgLoader.cpp @@ -76,7 +76,7 @@ bool JpgLoader::open(const string& path) } -bool JpgLoader::open(const char* data, uint32_t size, bool copy) +bool JpgLoader::open(const char* data, uint32_t size, bool copy, const string& resourcePath) { clear(); diff --git a/src/loaders/jpg/tvgJpgLoader.h b/src/loaders/jpg/tvgJpgLoader.h index fd39de97..6933f4c9 100644 --- a/src/loaders/jpg/tvgJpgLoader.h +++ b/src/loaders/jpg/tvgJpgLoader.h @@ -43,7 +43,7 @@ public: using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const string& resourcePath) override; bool read() override; bool close() override; diff --git a/src/loaders/lottie/tvgLottieLoader.cpp b/src/loaders/lottie/tvgLottieLoader.cpp index eec43a6a..e2714f61 100644 --- a/src/loaders/lottie/tvgLottieLoader.cpp +++ b/src/loaders/lottie/tvgLottieLoader.cpp @@ -206,7 +206,7 @@ bool LottieLoader::header() } -bool LottieLoader::open(const char* data, uint32_t size, bool copy) +bool LottieLoader::open(const char* data, uint32_t size, bool copy, const std::string& resourcePath) { clear(); @@ -226,6 +226,10 @@ bool LottieLoader::open(const char* data, uint32_t size, bool copy) this->size = size; this->copy = copy; + if (!resourcePath.empty()) { + this->dirName = strdup(resourcePath.c_str()); + } + return header(); } diff --git a/src/loaders/lottie/tvgLottieLoader.h b/src/loaders/lottie/tvgLottieLoader.h index 7a195120..ec886b66 100644 --- a/src/loaders/lottie/tvgLottieLoader.h +++ b/src/loaders/lottie/tvgLottieLoader.h @@ -51,7 +51,7 @@ public: //Lottie Loaders using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const std::string& resourcePath) override; bool resize(Paint* paint, float w, float h) override; bool read() override; bool close() override; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index 2d9a32a1..af803061 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -867,9 +867,9 @@ LottieImage* LottieParser::parseImage(const char* key) image->size = b64Decode(b64Data, length, &image->b64Data); //external image resource } else { - auto len = strlen(dirName) + strlen(subPath) + strlen(data) + 1; + auto len = strlen(dirName) + strlen(subPath) + strlen(data) + 2; image->path = static_cast(malloc(len)); - snprintf(image->path, len, "%s%s%s", dirName, subPath, data); + snprintf(image->path, len, "%s/%s%s", dirName, subPath, data); } image->prepare(); diff --git a/src/loaders/png/tvgPngLoader.cpp b/src/loaders/png/tvgPngLoader.cpp index dcda8554..cae1d749 100644 --- a/src/loaders/png/tvgPngLoader.cpp +++ b/src/loaders/png/tvgPngLoader.cpp @@ -117,7 +117,7 @@ finalize: } -bool PngLoader::open(const char* data, uint32_t size, bool copy) +bool PngLoader::open(const char* data, uint32_t size, bool copy, const string& resourcePath) { clear(); diff --git a/src/loaders/png/tvgPngLoader.h b/src/loaders/png/tvgPngLoader.h index 071279d2..cfccc69c 100644 --- a/src/loaders/png/tvgPngLoader.h +++ b/src/loaders/png/tvgPngLoader.h @@ -45,7 +45,7 @@ public: using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const string& resourcePath) override; bool read() override; bool close() override; diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index be99ec08..3ab5b719 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -3671,7 +3671,7 @@ bool SvgLoader::header() } -bool SvgLoader::open(const char* data, uint32_t size, bool copy) +bool SvgLoader::open(const char* data, uint32_t size, bool copy, const string& resourcePath) { clear(); diff --git a/src/loaders/svg/tvgSvgLoader.h b/src/loaders/svg/tvgSvgLoader.h index 4bac52e0..8e4dd58d 100644 --- a/src/loaders/svg/tvgSvgLoader.h +++ b/src/loaders/svg/tvgSvgLoader.h @@ -44,7 +44,7 @@ public: using LoadModule::open; bool open(const string& path) override; - bool open(const char* data, uint32_t size, bool copy) override; + bool open(const char* data, uint32_t size, bool copy, const string& resourcePath) override; bool resize(Paint* paint, float w, float h) override; bool read() override; bool close() override; diff --git a/src/loaders/tvg/tvgTvgLoader.cpp b/src/loaders/tvg/tvgTvgLoader.cpp index ab8aaa3d..a874318e 100644 --- a/src/loaders/tvg/tvgTvgLoader.cpp +++ b/src/loaders/tvg/tvgTvgLoader.cpp @@ -148,7 +148,7 @@ bool TvgLoader::open(const string &path) } -bool TvgLoader::open(const char *data, uint32_t size, bool copy) +bool TvgLoader::open(const char *data, uint32_t size, bool copy,const string& resourcePath) { clear(); diff --git a/src/loaders/tvg/tvgTvgLoader.h b/src/loaders/tvg/tvgTvgLoader.h index c24461de..19c7f283 100644 --- a/src/loaders/tvg/tvgTvgLoader.h +++ b/src/loaders/tvg/tvgTvgLoader.h @@ -46,7 +46,7 @@ public: using LoadModule::open; bool open(const string &path) override; - bool open(const char *data, uint32_t size, bool copy) override; + bool open(const char *data, uint32_t size, bool copy, const string& resourcePath) override; bool read() override; bool close() override; bool resize(Paint* paint, float w, float h) override; diff --git a/src/renderer/tvgLoadModule.h b/src/renderer/tvgLoadModule.h index cc94831a..7d4380c0 100644 --- a/src/renderer/tvgLoadModule.h +++ b/src/renderer/tvgLoadModule.h @@ -37,7 +37,7 @@ public: virtual ~LoadModule() {} virtual bool open(const string& path) { return false; } - virtual bool open(const char* data, uint32_t size, bool copy) { return false; } + virtual bool open(const char* data, uint32_t size, bool copy, const string& resourcePath = "") { return false; } //Override this if the vector-format has own resizing policy. virtual bool resize(Paint* paint, float w, float h) { return false; } diff --git a/src/renderer/tvgLoader.cpp b/src/renderer/tvgLoader.cpp index f3f7e15c..5c4ddf4d 100644 --- a/src/renderer/tvgLoader.cpp +++ b/src/renderer/tvgLoader.cpp @@ -212,12 +212,12 @@ shared_ptr LoaderMgr::loader(const string& path, bool* invalid) } -shared_ptr LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy) +shared_ptr LoaderMgr::loader(const char* data, uint32_t size, const string& mimeType, bool copy, const string& resourcePath) { //Try with the given MimeType if (!mimeType.empty()) { if (auto loader = _findByType(mimeType)) { - if (loader->open(data, size, copy)) { + if (loader->open(data, size, copy, resourcePath)) { return shared_ptr(loader); } else { TVGLOG("LOADER", "Given mimetype \"%s\" seems incorrect or not supported.", mimeType.c_str()); diff --git a/src/renderer/tvgLoader.h b/src/renderer/tvgLoader.h index 51bdabb7..13013f39 100644 --- a/src/renderer/tvgLoader.h +++ b/src/renderer/tvgLoader.h @@ -30,7 +30,7 @@ struct LoaderMgr static bool init(); static bool term(); static shared_ptr loader(const string& path, bool* invalid); - static shared_ptr loader(const char* data, uint32_t size, const string& mimeType, bool copy); + static shared_ptr loader(const char* data, uint32_t size, const string& mimeType, bool copy, const string& resourcePath); static shared_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool premultiplied, bool copy); }; diff --git a/src/renderer/tvgPicture.cpp b/src/renderer/tvgPicture.cpp index 82104d80..03817fbf 100644 --- a/src/renderer/tvgPicture.cpp +++ b/src/renderer/tvgPicture.cpp @@ -156,11 +156,11 @@ Result Picture::load(const std::string& path) noexcept } -Result Picture::load(const char* data, uint32_t size, const string& mimeType, bool copy) noexcept +Result Picture::load(const char* data, uint32_t size, const string& mimeType, bool copy, const string& resourcePath) noexcept { if (!data || size <= 0) return Result::InvalidArguments; - return pImpl->load(data, size, mimeType, copy); + return pImpl->load(data, size, mimeType, copy, resourcePath); } diff --git a/src/renderer/tvgPicture.h b/src/renderer/tvgPicture.h index 65a35fc6..e1aeae6e 100644 --- a/src/renderer/tvgPicture.h +++ b/src/renderer/tvgPicture.h @@ -162,11 +162,11 @@ struct Picture::Impl return Result::Success; } - Result load(const char* data, uint32_t size, const string& mimeType, bool copy) + Result load(const char* data, uint32_t size, const string& mimeType, bool copy, const string& resourcePath) { if (paint || surface) return Result::InsufficientCondition; if (loader) loader->close(); - loader = LoaderMgr::loader(data, size, mimeType, copy); + loader = LoaderMgr::loader(data, size, mimeType, copy, resourcePath); if (!loader) return Result::NonSupport; if (!loader->read()) return Result::Unknown; w = loader->w;