From 20ffc1f859c7a24892f7713c20f20a0cbeeaf34e Mon Sep 17 00:00:00 2001 From: subhransu mohanty Date: Mon, 14 Jan 2019 10:31:03 +0900 Subject: [PATCH] lottie/vector: added image loading support in vector. Change-Id: I37fd0c436ec396b186f78dfe1f0c0304204a942b --- CMakeLists.txt | 5 ++ src/vector/CMakeLists.txt | 1 + src/vector/meson.build | 6 ++ src/vector/vimageloader.cpp | 116 ++++++++++++++++++++++++++++++++++++ src/vector/vimageloader.h | 25 ++++++++ 5 files changed, 153 insertions(+) create mode 100644 src/vector/vimageloader.cpp create mode 100644 src/vector/vimageloader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e9b01d..34e994c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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" diff --git a/src/vector/CMakeLists.txt b/src/vector/CMakeLists.txt index 96c55d6..cbf9c98 100644 --- a/src/vector/CMakeLists.txt +++ b/src/vector/CMakeLists.txt @@ -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 diff --git a/src/vector/meson.build b/src/vector/meson.build index 338b87e..ed8b471 100644 --- a/src/vector/meson.build +++ b/src/vector/meson.build @@ -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 index 0000000..28a774a --- /dev/null +++ b/src/vector/vimageloader.cpp @@ -0,0 +1,116 @@ +#include "vimageloader.h" +#include "vdebug.h" +#include +#include + +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::~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 index 0000000..64bd865 --- /dev/null +++ b/src/vector/vimageloader.h @@ -0,0 +1,25 @@ +#ifndef VIMAGELOADER_H +#define VIMAGELOADER_H + +#include + +#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 mImpl; +}; + +#endif // VIMAGELOADER_H -- 2.34.1