Lift tess decoders into a static lib Add a packages/runtime/decoders project that can be reused by more projects than just the tess renderer. Diffs= b69ae1312 Lift tess decoders into a static lib (#5709) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head index db6aa2b..89affb8 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -baefd620c53ec3e11584bf95c10efe1377348446 +b69ae131259dd46e67c0be905b86b89d4f2ad20e
diff --git a/decoders/build/premake5.lua b/decoders/build/premake5.lua new file mode 100644 index 0000000..b9ec487 --- /dev/null +++ b/decoders/build/premake5.lua
@@ -0,0 +1,41 @@ +workspace 'rive' +configurations {"debug", "release"} + +require 'setup_compiler' + +rive = path.getabsolute("../../") + +dofile(rive .. '/dependencies/premake5_libpng.lua') + +project 'rive_decoders' + dependson 'libpng' + kind 'StaticLib' + language "C++" + cppdialect "C++17" + exceptionhandling "Off" + rtti "Off" + targetdir "%{cfg.buildcfg}" + objdir "obj/%{cfg.buildcfg}" + flags { "FatalWarnings" } + + includedirs { + '../include', + libpng, + } + + files { + '../src/**.cpp' + } + + filter "configurations:debug" + do + defines {"DEBUG"} + symbols "On" + end + + filter "configurations:release" + do + defines {"RELEASE"} + defines {"NDEBUG"} + optimize "On" + end
diff --git a/viewer/include/viewer/tess/bitmap_decoder.hpp b/decoders/include/rive/decoders/bitmap_decoder.hpp similarity index 88% rename from viewer/include/viewer/tess/bitmap_decoder.hpp rename to decoders/include/rive/decoders/bitmap_decoder.hpp index 0213a71..94a69f5 100644 --- a/viewer/include/viewer/tess/bitmap_decoder.hpp +++ b/decoders/include/rive/decoders/bitmap_decoder.hpp
@@ -1,8 +1,11 @@ +/* + * Copyright 2023 Rive + */ + #ifndef _RIVE_BITMAP_DECODER_HPP_ #define _RIVE_BITMAP_DECODER_HPP_ -#include "rive/rive_types.hpp" -#include "rive/span.hpp" +#include <memory> /// Bitmap will always take ownership of the bytes it is constructed with. class Bitmap @@ -37,10 +40,10 @@ size_t byteSize(PixelFormat format) const; size_t bytesPerPixel(PixelFormat format) const; - static std::unique_ptr<Bitmap> decode(rive::Span<const uint8_t> bytes); + static std::unique_ptr<Bitmap> decode(const uint8_t bytes[], size_t byteCount); // Change the pixel format (note this will resize bytes). void pixelFormat(PixelFormat format); }; -#endif \ No newline at end of file +#endif
diff --git a/viewer/src/tess/bitmap_decoder.cpp b/decoders/src/bitmap_decoder.cpp similarity index 78% rename from viewer/src/tess/bitmap_decoder.cpp rename to decoders/src/bitmap_decoder.cpp index b438740..48ef58d 100644 --- a/viewer/src/tess/bitmap_decoder.cpp +++ b/decoders/src/bitmap_decoder.cpp
@@ -1,5 +1,8 @@ -#ifdef RIVE_RENDERER_TESS -#include "viewer/tess/bitmap_decoder.hpp" +/* + * Copyright 2023 Rive + */ + +#include "rive/decoders/bitmap_decoder.hpp" #include <vector> Bitmap::Bitmap(uint32_t width, @@ -33,11 +36,11 @@ size_t Bitmap::byteSize() const { return byteSize(m_PixelFormat); } -std::unique_ptr<Bitmap> DecodePng(rive::Span<const uint8_t> bytes); -std::unique_ptr<Bitmap> DecodeJpeg(rive::Span<const uint8_t> bytes) { return nullptr; } -std::unique_ptr<Bitmap> DecodeWebP(rive::Span<const uint8_t> bytes) { return nullptr; } +std::unique_ptr<Bitmap> DecodePng(const uint8_t bytes[], size_t byteCount); +std::unique_ptr<Bitmap> DecodeJpeg(const uint8_t bytes[], size_t byteCount) { return nullptr; } +std::unique_ptr<Bitmap> DecodeWebP(const uint8_t bytes[], size_t byteCount) { return nullptr; } -using BitmapDecoder = std::unique_ptr<Bitmap> (*)(rive::Span<const uint8_t> bytes); +using BitmapDecoder = std::unique_ptr<Bitmap> (*)(const uint8_t bytes[], size_t byteCount); struct ImageFormat { const char* name; @@ -45,7 +48,7 @@ BitmapDecoder decodeImage; }; -std::unique_ptr<Bitmap> Bitmap::decode(rive::Span<const uint8_t> bytes) +std::unique_ptr<Bitmap> Bitmap::decode(const uint8_t bytes[], size_t byteCount) { static ImageFormat decoders[] = { { @@ -71,19 +74,19 @@ // Immediately discard decoders with fingerprints that are longer than // the file buffer. - if (recognizer.fingerprint.size() > bytes.size()) + if (recognizer.fingerprint.size() > byteCount) { continue; } // If the fingerprint doesn't match, discrd this decoder. These are all bytes so .size() is // fine here. - if (std::memcmp(fingerprint.data(), bytes.data(), fingerprint.size()) != 0) + if (std::memcmp(fingerprint.data(), bytes, fingerprint.size()) != 0) { continue; } - auto bitmap = recognizer.decodeImage(bytes); + auto bitmap = recognizer.decodeImage(bytes, byteCount); if (!bitmap) { fprintf(stderr, "Bitmap::decode - failed to decode a %s.\n", recognizer.name); @@ -117,4 +120,3 @@ m_Bytes = std::move(nextBytes); m_PixelFormat = format; } -#endif \ No newline at end of file
diff --git a/viewer/src/tess/decode_png.cpp b/decoders/src/decode_png.cpp similarity index 91% rename from viewer/src/tess/decode_png.cpp rename to decoders/src/decode_png.cpp index 63998f4..58a7a30 100644 --- a/viewer/src/tess/decode_png.cpp +++ b/decoders/src/decode_png.cpp
@@ -1,6 +1,10 @@ -#ifdef RIVE_RENDERER_TESS -#include "viewer/tess/bitmap_decoder.hpp" +/* + * Copyright 2023 Rive + */ + +#include "rive/decoders/bitmap_decoder.hpp" #include "png.h" +#include <algorithm> struct EncodedImageBuffer { @@ -28,7 +32,7 @@ } } -std::unique_ptr<Bitmap> DecodePng(rive::Span<const uint8_t> bytes) +std::unique_ptr<Bitmap> DecodePng(const uint8_t bytes[], size_t byteCount) { png_structp png_ptr; png_infop info_ptr; @@ -52,8 +56,8 @@ } EncodedImageBuffer stream = { - .bytes = bytes.data(), - .size = bytes.size(), + .bytes = bytes, + .size = byteCount, .position = 0, }; @@ -135,6 +139,5 @@ pixelFormat = Bitmap::PixelFormat::R; break; } - return rivestd::make_unique<Bitmap>(width, height, pixelFormat, pixelBuffer); + return std::make_unique<Bitmap>(width, height, pixelFormat, pixelBuffer); } -#endif \ No newline at end of file
diff --git a/viewer/build/premake5_viewer.lua b/viewer/build/premake5_viewer.lua index 3e5f9fb..0d100c0 100644 --- a/viewer/build/premake5_viewer.lua +++ b/viewer/build/premake5_viewer.lua
@@ -12,7 +12,7 @@ skia = dependencies .. '/skia' if _OPTIONS.renderer == 'tess' then - dofile(path.join(path.getabsolute(dependencies) .. '/../..', 'premake5_libpng.lua')) + dofile(rive .. '/decoders/build/premake5.lua') dofile(path.join(path.getabsolute(rive_tess) .. '/build', 'premake5_tess.lua')) else -- tess renderer includes this @@ -22,7 +22,7 @@ project 'rive_viewer' do if _OPTIONS.renderer == 'tess' then - dependson 'libpng' + dependson 'rive_decoders' end kind 'ConsoleApp' language 'C++' @@ -112,13 +112,14 @@ do includedirs { rive_tess .. '/include', - libpng + rive .. '/decoders/include', } defines { 'RIVE_RENDERER_TESS' } links { 'rive_tess_renderer', + 'rive_decoders', 'libpng', 'zlib' }
diff --git a/viewer/src/sample_tools/sample_atlas_packer.cpp b/viewer/src/sample_tools/sample_atlas_packer.cpp index 5848ef7..9f74cbe 100644 --- a/viewer/src/sample_tools/sample_atlas_packer.cpp +++ b/viewer/src/sample_tools/sample_atlas_packer.cpp
@@ -1,7 +1,7 @@ #ifdef RIVE_RENDERER_TESS #include "viewer/sample_tools/sample_atlas_packer.hpp" #include "utils/no_op_factory.hpp" -#include "viewer/tess/bitmap_decoder.hpp" +#include "rive/decoders/bitmap_decoder.hpp" #include "rive/file.hpp" #include "rive/assets/image_asset.hpp" #include "rive/tess/sokol/sokol_tess_renderer.hpp" @@ -29,7 +29,7 @@ { std::unique_ptr<RenderImage> decodeImage(Span<const uint8_t> bytes) override { - auto bitmap = Bitmap::decode(bytes); + auto bitmap = Bitmap::decode(bytes.data(), bytes.size()); if (bitmap) { // We have a bitmap, let's make an image. @@ -243,4 +243,4 @@ } } } -#endif \ No newline at end of file +#endif
diff --git a/viewer/src/tess/viewer_sokol_factory.cpp b/viewer/src/tess/viewer_sokol_factory.cpp index a403693..90a8feb 100644 --- a/viewer/src/tess/viewer_sokol_factory.cpp +++ b/viewer/src/tess/viewer_sokol_factory.cpp
@@ -1,12 +1,12 @@ #ifdef RIVE_RENDERER_TESS #include "viewer/tess/viewer_sokol_factory.hpp" -#include "viewer/tess/bitmap_decoder.hpp" +#include "rive/decoders/bitmap_decoder.hpp" #include "rive/tess/sokol/sokol_tess_renderer.hpp" #include "sokol_gfx.h" std::unique_ptr<rive::RenderImage> ViewerSokolFactory::decodeImage(rive::Span<const uint8_t> bytes) { - auto bitmap = Bitmap::decode(bytes); + auto bitmap = Bitmap::decode(bytes.data(), bytes.size()); if (bitmap) { // We have a bitmap, let's make an image. @@ -33,4 +33,4 @@ } return nullptr; } -#endif \ No newline at end of file +#endif