lottie/vector: added image loading support in vector. 34/197534/3
authorsubhransu mohanty <sub.mohanty@samsung.com>
Mon, 14 Jan 2019 01:31:03 +0000 (10:31 +0900)
committersubhransu mohanty <sub.mohanty@samsung.com>
Tue, 15 Jan 2019 07:25:57 +0000 (16:25 +0900)
Change-Id: I37fd0c436ec396b186f78dfe1f0c0304204a942b

CMakeLists.txt
src/vector/CMakeLists.txt
src/vector/meson.build
src/vector/vimageloader.cpp [new file with mode: 0644]
src/vector/vimageloader.h [new file with mode: 0644]

index 1e9b01d..34e994c 100644 (file)
@@ -35,6 +35,11 @@ target_link_libraries(lottie-player
                         "${CMAKE_THREAD_LIBS_INIT}"
                      )
 
+# for dlopen, dlsym and dlclose dependancy
+target_link_libraries(lottie-player
+                    PRIVATE
+                    ${CMAKE_DL_LIBS})
+
 target_link_libraries(lottie-player
                     PUBLIC
                          "-Wl,--no-undefined"
index 96c55d6..cbf9c98 100644 (file)
@@ -23,6 +23,7 @@ target_sources(lottie-player
         "${CMAKE_CURRENT_LIST_DIR}/vbezier.cpp"
         "${CMAKE_CURRENT_LIST_DIR}/vraster.cpp"
         "${CMAKE_CURRENT_LIST_DIR}/vdrawable.cpp"
+        "${CMAKE_CURRENT_LIST_DIR}/vimageloader.cpp"
     )
 
 target_include_directories(lottie-player
index 338b87e..ed8b471 100644 (file)
@@ -1,6 +1,7 @@
 
 subdir('freetype')
 subdir('pixman')
+subdir('stb')
 
 vector_dep = [freetype_dep]
 vector_dep += pixman_dep
@@ -24,6 +25,11 @@ source_file  += files('vdebug.cpp')
 source_file  += files('vinterpolator.cpp')
 source_file  += files('vbezier.cpp')
 source_file  += files('vraster.cpp')
+source_file  += files('vimageloader.cpp')
+
+# dl dependancy for dlopen, dlsym, dlclose symbol
+cc = meson.get_compiler('cpp')
+vector_dep += cc.find_library('dl', required : true)
 
 vector_dep += declare_dependency( include_directories : include_directories('.'),
                                   sources             : source_file
diff --git a/src/vector/vimageloader.cpp b/src/vector/vimageloader.cpp
new file mode 100644 (file)
index 0000000..28a774a
--- /dev/null
@@ -0,0 +1,116 @@
+#include "vimageloader.h"
+#include "vdebug.h"
+#include <dlfcn.h>
+#include <cstring>
+
+using lottie_image_load_f = unsigned char* (*)(char const *filename, int *x, int *y, int *comp, int req_comp);
+using lottie_image_free_f = void (*)(unsigned char *);
+
+struct VImageLoader::Impl
+{
+    void                    *dl_handle{nullptr};
+    lottie_image_load_f      lottie_image_load{nullptr};
+    lottie_image_free_f      lottie_image_free{nullptr};
+
+    Impl()
+    {
+        #ifdef __APPLE__
+            dl_handle = dlopen("liblottie-image-loader.dylib", RTLD_LAZY);
+        #else
+            dl_handle = dlopen("liblottie-image-loader.so", RTLD_LAZY);
+        #endif
+        if (!dl_handle)
+            vWarning<<"Failed to dlopen liblottie-image-loader library";
+        lottie_image_load = (lottie_image_load_f) dlsym(dl_handle, "lottie_image_load");
+        if (!lottie_image_load)
+            vWarning<<"Failed to find symbol lottie_image_load in liblottie-image-loader library";
+        lottie_image_free = (lottie_image_free_f) dlsym(dl_handle, "lottie_image_free");
+        if (!lottie_image_free)
+            vWarning<<"Failed to find symbol lottie_image_free in liblottie-image-loader library";
+    }
+    ~Impl()
+    {
+        if (dl_handle) dlclose(dl_handle);
+    }
+    VBitmap load(const char *fileName)
+    {
+        if (!lottie_image_load) return VBitmap();
+
+        int width, height, n;
+        unsigned char *data  = lottie_image_load(fileName, &width, &height, &n, 4);
+
+        if (!data) {
+            return VBitmap();
+        }
+
+        // premultiply alpha
+        if (n == 4)
+            convertToBGRAPremul(data, width, height);
+        else
+            convertToBGRA(data, width, height);
+
+        // create a bitmap of same size.
+        VBitmap result = VBitmap(width, height, VBitmap::Format::ARGB32_Premultiplied);
+
+        // copy the data to bitmap buffer
+        memcpy(result.data(), data, width * height * 4);
+
+        // free the image data
+        lottie_image_free(data);
+
+        return result;
+    }
+    /*
+     * convert from RGBA to BGRA and premultiply
+     */
+    void convertToBGRAPremul(unsigned char *bits, int width, int height)
+    {
+        int pixelCount = width * height;
+        unsigned char *pix = bits;
+        for (int i = 0; i < pixelCount; i++) {
+            unsigned char r = pix[0];
+            unsigned char g = pix[1];
+            unsigned char b = pix[2];
+            unsigned char a = pix[3];
+
+            r = (r * a) / 255;
+            g = (g * a) / 255;
+            b = (b * a) / 255;
+
+            pix[0] = b;
+            pix[1] = g;
+            pix[2] = r;
+
+            pix += 4;
+        }
+    }
+    /*
+     * convert from RGBA to BGRA
+     */
+    void convertToBGRA(unsigned char *bits, int width, int height)
+    {
+        int pixelCount = width * height;
+        unsigned char *pix = bits;
+        for (int i = 0; i < pixelCount; i++) {
+            unsigned char r = pix[0];
+            unsigned char b = pix[2];
+            pix[0] = b;
+            pix[2] = r;
+            pix += 4;
+        }
+    }
+};
+
+VImageLoader::VImageLoader():
+    mImpl(std::make_unique<VImageLoader::Impl>())
+{
+
+}
+
+VImageLoader::~VImageLoader() {}
+
+VBitmap VImageLoader::load(const char *fileName)
+{
+    return mImpl->load(fileName);
+}
+
diff --git a/src/vector/vimageloader.h b/src/vector/vimageloader.h
new file mode 100644 (file)
index 0000000..64bd865
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef VIMAGELOADER_H
+#define VIMAGELOADER_H
+
+#include <memory>
+
+#include "vbitmap.h"
+
+class VImageLoader
+{
+public:
+    static VImageLoader& instance()
+    {
+         static VImageLoader singleton;
+         return singleton;
+    }
+
+    VBitmap load(const char *fileName);
+    ~VImageLoader();
+private:
+    VImageLoader();
+    struct Impl;
+    std::unique_ptr<Impl> mImpl;
+};
+
+#endif // VIMAGELOADER_H