From 53d23e986284f3de61582000c26f628f8a140f35 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 19 Mar 2021 19:41:18 +0900 Subject: [PATCH] common picture: fix crash at picture duplication. A duplicated picture needs to access internal picture loader data to get its properties while rasterizing. But it missed the loader since it's not copied from origin. Thus, we fix this by sharing the internal loader among the duplications and origin. @Examples: Duplicate --- src/examples/Duplicate.cpp | 2 ++ src/examples/PixelImage.cpp | 4 ++-- src/lib/tvgLoaderMgr.cpp | 12 ++++++------ src/lib/tvgLoaderMgr.h | 6 +++--- src/lib/tvgPictureImpl.h | 13 ++++++++++--- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/examples/Duplicate.cpp b/src/examples/Duplicate.cpp index 5c6a3971..44780e48 100644 --- a/src/examples/Duplicate.cpp +++ b/src/examples/Duplicate.cpp @@ -113,6 +113,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) canvas->push(move(picture1)); canvas->push(move(picture2)); + + free(data); } } diff --git a/src/examples/PixelImage.cpp b/src/examples/PixelImage.cpp index 61d13000..8e42e14f 100644 --- a/src/examples/PixelImage.cpp +++ b/src/examples/PixelImage.cpp @@ -46,6 +46,8 @@ void tvgDrawCmds(tvg::Canvas* canvas) picture2->composite(move(circle), tvg::CompositeMethod::ClipPath); canvas->push(move(picture2)); + + free(data); } @@ -148,8 +150,6 @@ int main(int argc, char **argv) //Terminate ThorVG Engine tvg::Initializer::term(tvg::CanvasEngine::Sw); - if (data) free(data); - } else { cout << "engine is not supported" << endl; } diff --git a/src/lib/tvgLoaderMgr.cpp b/src/lib/tvgLoaderMgr.cpp index d41671c1..0e5eb1cb 100644 --- a/src/lib/tvgLoaderMgr.cpp +++ b/src/lib/tvgLoaderMgr.cpp @@ -89,22 +89,22 @@ bool LoaderMgr::term() } -unique_ptr LoaderMgr::loader(const string& path) +shared_ptr LoaderMgr::loader(const string& path) { if (auto loader = _find(path)) { - if (loader->open(path)) return unique_ptr(loader); + if (loader->open(path)) return shared_ptr(loader); else delete(loader); } return nullptr; } -unique_ptr LoaderMgr::loader(const char* data, uint32_t size) +shared_ptr LoaderMgr::loader(const char* data, uint32_t size) { for (int i = 0; i < static_cast(FileType::Unknown); i++) { auto loader = _find(static_cast(i)); if (loader) { - if (loader->open(data, size)) return unique_ptr(loader); + if (loader->open(data, size)) return shared_ptr(loader); else delete(loader); } } @@ -112,12 +112,12 @@ unique_ptr LoaderMgr::loader(const char* data, uint32_t size) } -unique_ptr LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) +shared_ptr LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy) { for (int i = 0; i < static_cast(FileType::Unknown); i++) { auto loader = _find(static_cast(i)); if (loader) { - if (loader->open(data, w, h, copy)) return unique_ptr(loader); + if (loader->open(data, w, h, copy)) return shared_ptr(loader); else delete(loader); } } diff --git a/src/lib/tvgLoaderMgr.h b/src/lib/tvgLoaderMgr.h index 5d2056ba..06d72597 100644 --- a/src/lib/tvgLoaderMgr.h +++ b/src/lib/tvgLoaderMgr.h @@ -30,9 +30,9 @@ struct LoaderMgr { static bool init(); static bool term(); - static unique_ptr loader(const string& path); - static unique_ptr loader(const char* data, uint32_t size); - static unique_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); + static shared_ptr loader(const string& path); + static shared_ptr loader(const char* data, uint32_t size); + static shared_ptr loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy); }; #endif //_TVG_LOADER_MGR_H_ diff --git a/src/lib/tvgPictureImpl.h b/src/lib/tvgPictureImpl.h index e3b0c5d5..2fc22672 100644 --- a/src/lib/tvgPictureImpl.h +++ b/src/lib/tvgPictureImpl.h @@ -32,7 +32,7 @@ struct Picture::Impl { - unique_ptr loader = nullptr; + shared_ptr loader = nullptr; Paint* paint = nullptr; uint32_t *pixels = nullptr; Picture *picture = nullptr; @@ -105,6 +105,7 @@ struct Picture::Impl } if (!pixels) { pixels = const_cast(loader->pixels()); + loader->close(); if (pixels) return RenderUpdateFlag::Image; } } @@ -195,11 +196,17 @@ struct Picture::Impl { reload(); - if (!paint) return nullptr; auto ret = Picture::gen(); if (!ret) return nullptr; + auto dup = ret.get()->pImpl; - dup->paint = paint->duplicate(); + if (paint) dup->paint = paint->duplicate(); + + dup->loader = loader; + dup->pixels = pixels; + dup->w = w; + dup->h = h; + dup->resizing = resizing; return ret.release(); }