common picture: fix crash at picture duplication.
authorHermet Park <hermetpark@gmail.com>
Fri, 19 Mar 2021 10:41:18 +0000 (19:41 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Mon, 22 Mar 2021 01:28:44 +0000 (10:28 +0900)
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
src/examples/PixelImage.cpp
src/lib/tvgLoaderMgr.cpp
src/lib/tvgLoaderMgr.h
src/lib/tvgPictureImpl.h

index 5c6a397..44780e4 100644 (file)
@@ -113,6 +113,8 @@ void tvgDrawCmds(tvg::Canvas* canvas)
 
         canvas->push(move(picture1));
         canvas->push(move(picture2));
+
+        free(data);
     }
 }
 
index 61d1300..8e42e14 100644 (file)
@@ -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;
     }
index d41671c..0e5eb1c 100644 (file)
@@ -89,22 +89,22 @@ bool LoaderMgr::term()
 }
 
 
-unique_ptr<Loader> LoaderMgr::loader(const string& path)
+shared_ptr<Loader> LoaderMgr::loader(const string& path)
 {
     if (auto loader = _find(path)) {
-        if (loader->open(path)) return unique_ptr<Loader>(loader);
+        if (loader->open(path)) return shared_ptr<Loader>(loader);
         else delete(loader);
     }
     return nullptr;
 }
 
 
-unique_ptr<Loader> LoaderMgr::loader(const char* data, uint32_t size)
+shared_ptr<Loader> LoaderMgr::loader(const char* data, uint32_t size)
 {
     for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) {
         auto loader = _find(static_cast<FileType>(i));
         if (loader) {
-            if (loader->open(data, size)) return unique_ptr<Loader>(loader);
+            if (loader->open(data, size)) return shared_ptr<Loader>(loader);
             else delete(loader);
         }
     }
@@ -112,12 +112,12 @@ unique_ptr<Loader> LoaderMgr::loader(const char* data, uint32_t size)
 }
 
 
-unique_ptr<Loader> LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
+shared_ptr<Loader> LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
 {
     for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) {
         auto loader = _find(static_cast<FileType>(i));
         if (loader) {
-            if (loader->open(data, w, h, copy)) return unique_ptr<Loader>(loader);
+            if (loader->open(data, w, h, copy)) return shared_ptr<Loader>(loader);
             else delete(loader);
         }
     }
index 5d2056b..06d7259 100644 (file)
@@ -30,9 +30,9 @@ struct LoaderMgr
 {
     static bool init();
     static bool term();
-    static unique_ptr<Loader> loader(const string& path);
-    static unique_ptr<Loader> loader(const char* data, uint32_t size);
-    static unique_ptr<Loader> loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy);
+    static shared_ptr<Loader> loader(const string& path);
+    static shared_ptr<Loader> loader(const char* data, uint32_t size);
+    static shared_ptr<Loader> loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy);
 };
 
 #endif //_TVG_LOADER_MGR_H_
index e3b0c5d..2fc2267 100644 (file)
@@ -32,7 +32,7 @@
 
 struct Picture::Impl
 {
-    unique_ptr<Loader> loader = nullptr;
+    shared_ptr<Loader> loader = nullptr;
     Paint* paint = nullptr;
     uint32_t *pixels = nullptr;
     Picture *picture = nullptr;
@@ -105,6 +105,7 @@ struct Picture::Impl
             }
             if (!pixels) {
                 pixels = const_cast<uint32_t*>(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();
     }