From 832568e07ae69ac33ad32928527d15d4422c6ba6 Mon Sep 17 00:00:00 2001 From: Mateusz Palkowski Date: Mon, 8 Mar 2021 13:38:37 +0100 Subject: [PATCH] Added libpng based png loading --- meson.build | 4 +++ meson_options.txt | 5 +++ src/lib/tvgLoaderMgr.cpp | 12 ++++++++ src/lib/tvgLoaderMgr.h | 2 +- src/loaders/meson.build | 4 +++ src/loaders/png/meson.build | 9 ++++++ src/loaders/png/tvgPngLoader.cpp | 52 ++++++++++++++++++++++++++++++++ src/loaders/png/tvgPngLoader.h | 22 ++++++++++++++ src/meson.build | 6 ++++ 9 files changed, 115 insertions(+), 1 deletion(-) create mode 100755 src/loaders/png/meson.build create mode 100755 src/loaders/png/tvgPngLoader.cpp create mode 100755 src/loaders/png/tvgPngLoader.h diff --git a/meson.build b/meson.build index 9da044d7..b2cd9571 100644 --- a/meson.build +++ b/meson.build @@ -33,6 +33,10 @@ if get_option('log') == true message('Enable Log') endif +if get_option('png') == true + config_h.set10('THORVG_PNG_LOADER_SUPPORT', true) +endif + configure_file( output: 'config.h', configuration: config_h diff --git a/meson_options.txt b/meson_options.txt index 4a187853..ca0bd3ed 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -33,6 +33,11 @@ option('examples', value: false, description: 'Enable building examples') +option('png', + type: 'boolean', + value: false, + description: 'Enable libpng based png loading') + option('test', type: 'boolean', value: false, diff --git a/src/lib/tvgLoaderMgr.cpp b/src/lib/tvgLoaderMgr.cpp index 474b8e57..f6076032 100644 --- a/src/lib/tvgLoaderMgr.cpp +++ b/src/lib/tvgLoaderMgr.cpp @@ -24,6 +24,11 @@ #ifdef THORVG_SVG_LOADER_SUPPORT #include "tvgSvgLoader.h" #endif + +#ifdef THORVG_PNG_LOADER_SUPPORT + #include "tvgPngLoader.h" +#endif + #include "tvgRawLoader.h" /************************************************************************/ @@ -39,6 +44,12 @@ static Loader* _find(FileType type) case FileType::Svg: { #ifdef THORVG_SVG_LOADER_SUPPORT return new SvgLoader; +#endif + break; + } + case FileType::Png: { +#ifdef THORVG_PNG_LOADER_SUPPORT + return new PngLoader; #endif break; } @@ -58,6 +69,7 @@ static Loader* _find(const string& path) { auto ext = path.substr(path.find_last_of(".") + 1); if (!ext.compare("svg")) return _find(FileType::Svg); + if (!ext.compare("png")) return _find(FileType::Png); return nullptr; } diff --git a/src/lib/tvgLoaderMgr.h b/src/lib/tvgLoaderMgr.h index 28ab1e3b..98511476 100644 --- a/src/lib/tvgLoaderMgr.h +++ b/src/lib/tvgLoaderMgr.h @@ -24,7 +24,7 @@ #include "tvgLoader.h" -enum class FileType { Svg = 0, Raw, Unknown }; +enum class FileType { Svg = 0, Raw, Png, Unknown }; struct LoaderMgr { diff --git a/src/loaders/meson.build b/src/loaders/meson.build index 345497ee..e858968d 100644 --- a/src/loaders/meson.build +++ b/src/loaders/meson.build @@ -5,6 +5,10 @@ if get_option('loaders').contains('svg') == true message('Enable SVG Loader') endif +if get_option('png') == true + subdir('png') +endif + subdir('raw') loader_dep = declare_dependency( diff --git a/src/loaders/png/meson.build b/src/loaders/png/meson.build new file mode 100755 index 00000000..1de51742 --- /dev/null +++ b/src/loaders/png/meson.build @@ -0,0 +1,9 @@ +source_file = [ + 'tvgPngLoader.h', + 'tvgPngLoader.cpp', +] + +subloader_dep += [declare_dependency( + include_directories : include_directories('.'), + sources : source_file +)] diff --git a/src/loaders/png/tvgPngLoader.cpp b/src/loaders/png/tvgPngLoader.cpp new file mode 100755 index 00000000..e74e8a02 --- /dev/null +++ b/src/loaders/png/tvgPngLoader.cpp @@ -0,0 +1,52 @@ +#include +#include +#include "tvgLoaderMgr.h" +#include "tvgPngLoader.h" +// #include "png.h" + +PngLoader::~PngLoader() +{ + if (content) { + free((void*)content); + content = nullptr; + } +} + +bool PngLoader::open(const string& path) +{ + png_image image; + image.version = PNG_IMAGE_VERSION; + image.opaque = NULL; + + if (!png_image_begin_read_from_file(&image, path.c_str())) return false; + w = image.width; + h = image.height; + vw = w; + vh = h; + png_bytep buffer; + image.format = PNG_FORMAT_BGRA; + buffer = static_cast(malloc(PNG_IMAGE_SIZE(image))); + if (!buffer) { + // out of memory, only time when libpng doesnt free its data + png_image_free(&image); + return false; + } + if (!png_image_finish_read(&image, NULL, buffer, 0, NULL)) return false; + content = reinterpret_cast(buffer); + return true; +} + +bool PngLoader::read() +{ + return true; +} + +bool PngLoader::close() +{ + return true; +} + +const uint32_t* PngLoader::pixels() +{ + return this->content; +} diff --git a/src/loaders/png/tvgPngLoader.h b/src/loaders/png/tvgPngLoader.h new file mode 100755 index 00000000..bf233e31 --- /dev/null +++ b/src/loaders/png/tvgPngLoader.h @@ -0,0 +1,22 @@ +#ifndef _TVG_PNG_LOADER_H_ +#define _TVG_PNG_LOADER_H_ + +#include + +class PngLoader : public Loader +{ +public: + const uint32_t* content = nullptr; + + ~PngLoader(); + + using Loader::open; + bool open(const string& path) override; + bool read() override; + bool close() override; + + const uint32_t* pixels() override; +}; + + +#endif //_TVG_PNG_LOADER_H_ \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 7e19d039..188c9da0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -19,6 +19,12 @@ subdir('bindings') thread_dep = meson.get_compiler('cpp').find_library('pthread') thorvg_lib_dep = [common_dep, loader_dep, binding_dep, thread_dep] +if get_option('png') == true + message('Enable libpng based png loading') + png_dep = meson.get_compiler('cpp').find_library('libpng') + thorvg_lib_dep += png_dep +endif + thorvg_lib = library( 'thorvg', include_directories : headers,