rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime

rlottie

Build Status Build status Gitter

rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime.

Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with bodymovin, Sketch with Lottie Sketch Export, and from Haiku.

For the first time, designers can create and ship beautiful animations without an engineer painstakingly recreating it by hand. Since the animation is backed by JSON they are extremely small in size but can be large in complexity!

Here are small samples of the power of Lottie.

Contents

Building Lottie

rlottie supports meson and cmake build system. rlottie is written in C++14. and has a public header dependency of C++11

Meson Build

install meson and ninja if not already installed.

Run meson to configure rlottie

meson build

Run ninja to build rlottie

ninja -C build

Cmake Build

Install cmake if not already installed

Create a build directory for out of source build

mkdir build

Run cmake command inside build directory to configure rlottie.

cd build
cmake ..

# install in a different path. eg ~/test/usr/lib
cmake -DCMAKE_INSTALL_PREFIX=~/test ..

# static build
cmake -DBUILD_SHARED_LIBS=OFF ..

Run make to build rlottie

make -j 2

To install rlottie library

make install

Test

Configure to build test

meson configure -Dtest=true

Build test suit

ninja

Run test suit

ninja test

Back to contents

Demo

If you want to see rlottie library in action without building it please visit rlottie online viewer

While building rlottie library it generates a simple lottie to GIF converter which can be used to convert lottie json file to GIF file.

Run Demo

lottie2gif [lottie file name]

Previewing Lottie JSON Files

Please visit rlottie online viewer

rlottie online viewer uses rlottie wasm library to render the resource locally in your browser. To test your JSON resource drag and drop it to the browser window.

Quick Start

Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with bodymovin, Sketch with Lottie Sketch Export, and from Haiku.

You can quickly load a Lottie animation with:

auto animation = rlottie::Animation::loadFromFile("absolute_path/test.json");

You can load a lottie animation from raw data with:

auto animation = rlottie::Animation::loadFromData(std::string(rawData), std::string(cacheKey));

Properties like frameRate , totalFrame , duration can be queried with:

# get the frame rate of the resource.
double frameRate = animation->frameRate();

#get total frame that exists in the resource
size_t totalFrame = animation->totalFrame();

#get total animation duration in sec for the resource
double duration = animation->duration();

Render a particular frame in a surface buffer immediately with:

rlottie::Surface surface(buffer, width , height , stride);
animation->renderSync(frameNo, surface);

Render a particular frame in a surface buffer asyncronousely with:

rlottie::Surface surface(buffer, width , height , stride);
# give a render request
std::future
    handle = animation->
   render(frameNo, surface);
...
#when the render data is needed
rlottie::Surface surface = handle.get();
  

Back to contents

Dynamic Property

You can update properties dynamically at runtime. This can be used for a variety of purposes such as:

  • Theming (day and night or arbitrary themes).
  • Responding to events such as an error or a success.
  • Animating a single part of an animation in response to an event.
  • Responding to view sizes or other values not known at design time.

Understanding After Effects

To understand how to change animation properties in Lottie, you should first understand how animation properties are stored in Lottie. Animation properties are stored in a data tree that mimics the information hierarchy of After Effects. In After Effects a Composition is a collection of Layers that each have their own timelines. Layer objects have string names, and their contents can be an image, shape layers, fills, strokes, or just about anything that is drawable. Each object in After Effects has a name. Lottie can find these objects and properties by their name using a KeyPath.

Usage

To update a property at runtime, you need 3 things:

  1. KeyPath
  2. rLottie::Property
  3. setValue()

KeyPath

A KeyPath is used to target a specific content or a set of contents that will be updated. A KeyPath is specified by a list of strings that correspond to the hierarchy of After Effects contents in the original animation. KeyPaths can include the specific name of the contents or wildcards:

  • Wildcard *
    • Wildcards match any single content name in its position in the keypath.
  • Globstar **
    • Globstars match zero or more layers.

Properties

rLottie::Property is an enumeration of properties that can be set. They correspond to the animatable value in After Effects and the available properties are listed below.

enum class Property {
    FillColor,     /*!< Color property of Fill object , value type is rlottie::Color */
    FillOpacity,   /*!< Opacity property of Fill object , value type is float [ 0 .. 100] */
    StrokeColor,   /*!< Color property of Stroke object , value type is rlottie::Color */
    StrokeOpacity, /*!< Opacity property of Stroke object , value type is float [ 0 .. 100] */
    StrokeWidth,   /*!< stroke with property of Stroke object , value type is float */
    ...
};

setValue()

setValue() requires a keypath of string and value. The value can be Color, Size and Point structure or a function that returns them. Color, Size, and Point vary depending on the type of rLottie::Property. This value or function(callback) is called and applied to every frame. This value can be set differently for each frame by using the FrameInfo argument passed to the function.

Usage

animation->setValue
   (
   "**",rlottie::Color(
   0, 
   1, 
   0));
  
animation->setValue
   (
   "Layer1.Box 1.Fill1",
    [](
   const rlottie::FrameInfo& info) {
         
   if (info.
   curFrame() < 
   15 )
             
   return 
   rlottie::Color(
   0, 
   1, 
   0);
         
   else {
             
   return 
   rlottie::Color(
   1, 
   0, 
   0);
         }
     });
  

Back to contents

Supported After Effects Features

Shapes Supported
Shape πŸ‘
Ellipse πŸ‘
Rectangle πŸ‘
Rounded Rectangle πŸ‘
Polystar πŸ‘
Group πŸ‘
Trim Path (individually) πŸ‘
Trim Path (simultaneously) πŸ‘
Renderable Supported
Fill πŸ‘
Stroke πŸ‘
Radial Gradient πŸ‘
Linear Gradient πŸ‘
Gradient Stroke πŸ‘
Transforms Supported
Position πŸ‘
Position (separated X/Y) πŸ‘
Scale πŸ‘
Skew ⛔️
Rotation πŸ‘
Anchor Point πŸ‘
Opacity πŸ‘
Parenting πŸ‘
Auto Orient πŸ‘
Interpolation Supported
Linear Interpolation πŸ‘
Bezier Interpolation πŸ‘
Hold Interpolation πŸ‘
Spatial Bezier Interpolation πŸ‘
Rove Across Time πŸ‘
Masks Supported
Mask Path πŸ‘
Mask Opacity πŸ‘
Add πŸ‘
Subtract πŸ‘
Intersect πŸ‘
Lighten ⛔️
Darken ⛔️
Difference ⛔️
Expansion ⛔️
Feather ⛔️
Mattes Supported
Alpha Matte πŸ‘
Alpha Inverted Matte πŸ‘
Luma Matte πŸ‘
Luma Inverted Matte πŸ‘
Merge Paths Supported
Merge ⛔️
Add ⛔️
Subtract ⛔️
Intersect ⛔️
Exclude Intersection ⛔️
Layer Effects Supported
Fill ⛔️
Stroke ⛔️
Tint ⛔️
Tritone ⛔️
Levels Individual Controls ⛔️
Text Supported
Glyphs ⛔️
Fonts ⛔️
Transform ⛔️
Fill ⛔️
Stroke ⛔️
Tracking ⛔️
Anchor point grouping ⛔️
Text Path ⛔️
Per-character 3D ⛔️
Range selector (Units) ⛔️
Range selector (Based on) ⛔️
Range selector (Amount) ⛔️
Range selector (Shape) ⛔️
Range selector (Ease High) ⛔️
Range selector (Ease Low) ⛔️
Range selector (Randomize order) ⛔️
expression selector ⛔️
Other Supported
Expressions ⛔️
Images πŸ‘
Precomps πŸ‘
Time Stretch πŸ‘
Time remap πŸ‘
Markers πŸ‘

Back to contents

Issues or Feature Requests?

File github issues for anything that is broken. Be sure to check the list of supported features before submitting. If an animation is not working, please attach the After Effects file to your issue. Debugging without the original can be very difficult. For immidiate assistant or support please reach us in Gitter

Owner
Samsung
Samsung Electronics Co.,Ltd.
Samsung
Comments
  • Integrating with Godot Engine / License

    Integrating with Godot Engine / License

    Describe the project you are working on:

    Multiplayer game.

    Describe the problem or limitation you are having in your project:

    Want to play animated vector graphics.

    Describe the feature / enhancement and how it helps to overcome the problem or limitation:

    Adding telegram / Lottie animations to Godot Engine.

    Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

    Wanted to use rlottie, but LGPL is not compatible with MIT license. Godot Engine is a single executable so LGPL does not apply.

    Need to get rlottie to output into a format where there's individual shapes / meshes and then transforms are applied on the group.

  • Color red becomes purple on android

    Color red becomes purple on android

    All rlottie frame's red color becomes purple. The issue happens only on newer versions of rlottie lib code. The older version on telegram works fine.

    image Become image

  • [rlottie] C API does not render pixel data in the surface buffer.

    [rlottie] C API does not render pixel data in the surface buffer.

    main.zip Attached the test source code.

    Expectation: After executing the code, I expect to see some pixel data in the surface buffer. Actual behaviour: After flushing the rendering data, the buffer content is still zero. See attached GDB picture.

    To build the source code: gcc -Lbuild/src/ -Wall -g -Og -o vtest main.c -lrlottie

    BufferContentAfterRendering

  • Expose Composition

    Expose Composition

    In addition to rendering to a surface, is it possible to expose Composition?

    The goal is to get the paths that are in the composition and layers and convert the model to a format a 2d vector player can handle.

    Not sure how to handle the conversion of the paths and layers in the animation (that can be disabled) and recreating an animation player. See https://docs.godotengine.org/en/stable/classes/class_animationplayer.html.

    Instead of:

    std::unique_ptr<rlottie::Animation> lottie =
    			rlottie::Animation::loadFromFile(path.utf8().ptr());
    // ...
    lottie->renderSync(frame_i, surface);
    

    We can do:

    std::unique_ptr<rlottie::Animation> lottie =
    			rlottie::Animation::loadFromFile(path.utf8().ptr());
    rlottie::Composition composition = lottie->renderModel()
    
    class Composition : public Object {
    public:
        Composition() : Object(Object::Type::Composition) {}
        std::vector<LayerInfo>     layerInfoList() const;
        const std::vector<Marker> &markers() const { return mMarkers; }
        double                     duration() const
        {
            return frameDuration() / frameRate();  // in second
        }
        size_t frameAtPos(double pos) const
        {
            if (pos < 0) pos = 0;
            if (pos > 1) pos = 1;
            return size_t(round(pos * frameDuration()));
        }
        long frameAtTime(double timeInSec) const
        {
            return long(frameAtPos(timeInSec / duration()));
        }
        size_t totalFrame() const { return mEndFrame - mStartFrame; }
        long   frameDuration() const { return mEndFrame - mStartFrame - 1; }
        float  frameRate() const { return mFrameRate; }
        size_t startFrame() const { return mStartFrame; }
        size_t endFrame() const { return mEndFrame; }
        VSize  size() const { return mSize; }
        void   processRepeaterObjects();
        void   updateStats();
    
    public:
        struct Stats {
            uint16_t precompLayerCount{0};
            uint16_t solidLayerCount{0};
            uint16_t shapeLayerCount{0};
            uint16_t imageLayerCount{0};
            uint16_t nullLayerCount{0};
        };
    
    public:
        std::string                              mVersion;
        VSize                                    mSize;
        long                                     mStartFrame{0};
        long                                     mEndFrame{0};
        float                                    mFrameRate{60};
        BlendMode                                mBlendMode{BlendMode::Normal};
        Layer *                                  mRootLayer{nullptr};
        std::unordered_map<std::string, Asset *> mAssets;
    
        std::vector<Marker> mMarkers;
        VArenaAlloc         mArenaAlloc{2048};
        Stats               mStats;
    };
    
  • render problem

    render problem

    I have tested some simple compositions as followed. But some strange problems have appeared.

    1. when rendering shapes, it has black edges, however in AE file is not contained.
    2. it seems that the shapes with opacity is not support?
    3. when rendering images, especially the image moved or zoomed in/out, the texture is incoherently if you concat them to a video and has some color blocks.

    hope for your reply! thanks~

    shape.aep.zip image aep.zip ζˆͺ屏2020-03-26上午10 56 56

  • image's opacity and  Gaussian blur

    image's opacity and Gaussian blur

    Our test json has image layers with opacity(not 100) or Gaussian blur, I wonder can rlottie render these effect or not.

    Below is our json and images. img_0.png has 10 transparency. img_11.png is gaussian blurred. Thanks~ test.zip

  • Allow passing a color replacement map.

    Allow passing a color replacement map.

    Hi. I have a need to be able to replace colors by a map (color -> color) in a loading animation.

    I understand that this may be just a not welcome feature in your library, but different Linux package maintainers are not happy that they can't use upstream rlottie instead of my fork, so I ask if this feature could make it here in any form.

    This is my sample straightforward implementation. The alternative was for me to decode the json, go through and replace the colors and encode back before passing it to rlottie - overhead is too big for me, bad idea.

    If you agree to add such feature but with different design approach please let me know, I'm ready to implement a different way of doing the same (color format, whatever), just without large runtime overhead.

  • Windows: M_PI undefined

    Windows: M_PI undefined

    On Windows M_PI is defined only if

    #define _USE_MATH_DEFINES

    is called just before #include in src/lottie/lottiemodel.cpp, src/vector/vdasher.cpp, vbezier.cpp and vpath.cpp too. See

    https://docs.microsoft.com/fr-fr/cpp/c-runtime-library/math-constants?view=vs-2019

    you can, if you want, embed this macro in a #ifdef_WIN32

  • Release build failing to parse, Debug - ok

    Release build failing to parse, Debug - ok

    Building rlottie static to Debug and Release on macOS x64 10.14.6

    If build in Debug (-DCMAKE_BUILD_TYPE=Debug) - file parses ok, image renders. If build in Release (Release, RelWithDebInfo or MinSizeRel) - parser fails. Failing method is void LottieParserImpl::parseComposition() - Debug and Release behave differentry in while (const char *key = NextObjectKey()) { ... } loop.

    In Debug it loops over all objects, in Release - it misses layers and some others, what leads if (comp->mVersion.empty() || !comp->mRootLayer) to fail.

    sample file: https://assets4.lottiefiles.com/packages/lf20_GsFUFN.json

  • bodymovin upgrade test

    bodymovin upgrade test

    Bodymovin 5.5.2 version is released, there is a report rlottie doens't work on it. Need to verify rlottie with any sample resource exported that version whether it's working or not

  • Optimize compatibility with windows

    Optimize compatibility with windows

    1.On windows, stbi__fopen opens a path containing non-English characters or symbols will fail due to encoding problems, so the filename parameter is assumed to be utf-8 and converted to utf-16, and then call _wfopen_s or _wfopen 2. In Windows 7 multithreading mode, unloading rlottie.dll will cause the process to be stuck and unable to exit. You need to actively stop RleTaskScheduler before main return

  • Use after free in surface cache code

    Use after free in surface cache code

    Found this via Valgrind:

       VBitmap make_surface(
            size_t width, size_t height,
            VBitmap::Format format = VBitmap::Format::ARGB32_Premultiplied)
        {
            if (mCache.empty()) return {width, height, format};
    
            auto surface = mCache.back();
            surface.reset(width, height, format);
    
            mCache.pop_back();
            return surface;
        }
    
        void release_surface(VBitmap &surface) { mCache.push_back(surface); }
    

    Here we have the sequence:

    1. VBitmap & surface = mCache.back() => we take a reference on the last element
    2. cache.pop_back(); => delete the last element in the vector
    3. return surface; => return a dangling reference on a deleted element

    Instead of auto surface here, it should be VBitmap surface since auto resolve to a reference (vector::back() returns a reference on its last element)

  • Result of fuzzing tests

    Result of fuzzing tests

    I did some fuzzing and found six interesting JSONs that cause to crashes or undefined behaviour. It would be great to have them fixed.

    Case 1

    Valgrid noticed usage of uninitialized values. 001f.json {"v":"0","op":9,"layers":[{"ddd":0,"ks":{"r":{"k":[{"i":{},"":0}]}},"op":1}]}

    Click to see output (valgrind ...)
    [email protected]:~/rlottie$ valgrind --track-origins=yes build/example/lottie2gif fuzz/collect/001f.json
    ==1821184== Memcheck, a memory error detector
    ==1821184== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==1821184== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
    ==1821184== Command: build/example/lottie2gif fuzz/collect/001f.json
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899F2F: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:240)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899F3C: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:240)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899F71: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:244)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899F82: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:244)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899F93: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:244)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899FA4: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:244)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899FCA: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:246)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899FDB: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:246)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899FEC: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:246)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4899FFD: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:246)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x489A023: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:248)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x489A034: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:248)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4DFE17F: __sinf_fma (s_sinf.c:45)
    ==1821184==    by 0x489CD50: std::sin(float) (cmath:426)
    ==1821184==    by 0x489A072: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:252)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4DFE1C9: __sinf_fma (s_sinf.c:59)
    ==1821184==    by 0x489CD50: std::sin(float) (cmath:426)
    ==1821184==    by 0x489A072: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:252)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4DFE285: __sinf_fma (s_sinf.c:71)
    ==1821184==    by 0x489CD50: std::sin(float) (cmath:426)
    ==1821184==    by 0x489A072: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:252)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Use of uninitialised value of size 8
    ==1821184==    at 0x4DFE2C0: reduce_large (s_sincosf.h:84)
    ==1821184==    by 0x4DFE2C0: __sinf_fma (s_sinf.c:76)
    ==1821184==    by 0x489CD50: std::sin(float) (cmath:426)
    ==1821184==    by 0x489A072: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:252)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x4DFE32D: sinf_poly (sincosf_poly.h:90)
    ==1821184==    by 0x4DFE32D: __sinf_fma (s_sinf.c:84)
    ==1821184==    by 0x489CD50: std::sin(float) (cmath:426)
    ==1821184==    by 0x489A072: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:252)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==  Uninitialised value was created by a stack allocation
    ==1821184==    at 0x48E41FA: void LottieParserImpl::parseKeyFrame<float, void>(rlottie::internal::model::KeyFrames<float, void>&) (lottieparser.cpp:2010)
    ==1821184== 
    ==1821184== Use of uninitialised value of size 8
    ==1821184==    at 0x4DFE332: sinf_poly (sincosf_poly.h:93)
    ==1821184==    by 0x4DFE332: __sinf_fma (s_sinf.c:84)
    ==1821184==    by 0x489CD50: std::sin(float) (cmath:426)
    ==1821184==    by 0x489A072: VMatrix::rotate(float, VMatrix::Axis) (vmatrix.cpp:252)
    ==1821184==    by 0x48C968F: rlottie::internal::model::Transform::Data::matrix(int, bool) const (lottiemodel.cpp:197)
    ==1821184==    by 0x48AE69D: rlottie::internal::model::Transform::matrix(int, bool) const (lottiemodel.h:618)
    ==1821184==    by 0x48AE918: rlottie::internal::model::Layer::matrix(int) const (lottiemodel.h:700)
    ==1821184==    by 0x48A7C3D: rlottie::internal::renderer::Layer::matrix(int) const (lottieitem.cpp:440)
    ==1821184==    by 0x48A79D9: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:404)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==  Uninitialised value was created by a stack allocation
    ... truncated because of GitHub limits ...
    ==1821184== Conditional jump or move depends on uninitialised value(s)
    ==1821184==    at 0x489BB8C: VMatrix::fuzzyCompare(VMatrix const&) const (vmatrix.cpp:557)
    ==1821184==    by 0x489BB2C: VMatrix::operator==(VMatrix const&) const (vmatrix.cpp:545)
    ==1821184==    by 0x489BB56: VMatrix::operator!=(VMatrix const&) const (vmatrix.cpp:550)
    ==1821184==    by 0x48A7A03: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:408)
    ==1821184==    by 0x48A8DF4: rlottie::internal::renderer::CompLayer::updateContent() (lottieitem.cpp:653)
    ==1821184==    by 0x48A7B60: rlottie::internal::renderer::Layer::update(int, VMatrix const&, float) (lottieitem.cpp:430)
    ==1821184==    by 0x48A62F1: rlottie::internal::renderer::Composition::update(int, VSize const&, bool) (lottieitem.cpp:146)
    ==1821184==    by 0x48F6E79: AnimationImpl::update(unsigned long, VSize const&, bool) (lottieanimation.cpp:105)
    ==1821184==    by 0x48F6F90: AnimationImpl::render(unsigned long, rlottie::Surface const&, bool) (lottieanimation.cpp:118)
    ==1821184==    by 0x48F7AF3: rlottie::Animation::renderSync(unsigned long, rlottie::Surface, bool) (lottieanimation.cpp:371)
    ==1821184==    by 0x10F300: App::render(unsigned int, unsigned int) (lottie2gif.cpp:91)
    ==1821184==    by 0x10EC34: main (lottie2gif.cpp:175)
    ==1821184== 
    Generated GIF file : 001f.json.gif
    ==1821184== 
    ==1821184== HEAP SUMMARY:
    ==1821184==     in use at exit: 0 bytes in 0 blocks
    ==1821184==   total heap usage: 47 allocs, 47 frees, 20,727,784 bytes allocated
    ==1821184== 
    ==1821184== All heap blocks were freed -- no leaks are possible
    ==1821184== 
    ==1821184== For lists of detected and suppressed errors, rerun with: -s
    ==1821184== ERROR SUMMARY: 28 errors from 28 contexts (suppressed: 0 from 0)
    

    Case 2

    Accessing elements of empty vector. 002f.json {"v":"0","op":1,"layers":[{"ty":4,"ks":{},"shapes":[{"ty":"gr","it":[{"ty":"sh","ks":{"k":[{}]}}]}],"op":1}]}

    Click to see output (gdb ...)
    [email protected]:~/rlottie$ gdb -ex run -ex bt\ full -ex q --args build/example/lottie2gif fuzz/collect/002f.json
    Reading symbols from build/example/lottie2gif...
    Starting program: /home/mymedia/rlottie/build/example/lottie2gif fuzz/collect/002f.json
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    
    Program received signal SIGSEGV, Segmentation fault.
    rlottie::internal::model::Property<rlottie::internal::model::PathData, void>::value<rlottie::internal::model::PathData> (this=0x555555573968, frameNo=0, path=...) at ./src/lottie/lottiemodel.h:343
    343                 if (vec.front().start_ >= frameNo)
    #0  rlottie::internal::model::Property<rlottie::internal::model::PathData, void>::value<rlottie::internal::model::PathData> (this=0x555555573968, frameNo=0, path=...) at ./src/lottie/lottiemodel.h:343
            vec = std::vector of length 0, capacity 0
    #1  0x00007ffff7f5e2dc in rlottie::internal::renderer::Path::updatePath (this=0x555555574360, path=..., frameNo=0) at ./src/lottie/lottieitem.cpp:1141
    No locals.
    #2  0x00007ffff7f5ddab in rlottie::internal::renderer::Shape::update (this=0x555555574360, frameNo=0, flag=...) at ./src/lottie/lottieitem.cpp:1082
    No locals.
    #3  0x00007ffff7f5d8c1 in rlottie::internal::renderer::Group::update (this=0x555555574300, frameNo=0, parentMatrix=..., parentAlpha=1, flag=...) at ./src/lottie/lottieitem.cpp:971
            content = @0x5555555749d0: 0x555555574360
            __for_range = std::vector of length 1, capacity 1 = {0x555555574360}
            __for_begin = 0x555555574360
            __for_end = 0x7ffff7caccc0 <main_arena+96>
            newFlag = {i = 3}
            alpha = 1
    #4  0x00007ffff7f5d8c1 in rlottie::internal::renderer::Group::update (this=0x5555555742a0, frameNo=0, parentMatrix=..., parentAlpha=1, flag=...) at ./src/lottie/lottieitem.cpp:971
            content = @0x5555555749b0: 0x555555574300
            __for_range = std::vector of length 1, capacity 1 = {0x555555574300}
            __for_begin = 0x555555574300
            __for_end = 0x7ffff7caccc0 <main_arena+96>
            newFlag = {i = 3}
            alpha = 1
    #5  0x00007ffff7f5cb3e in rlottie::internal::renderer::ShapeLayer::updateContent (this=0x555555574218) at ./src/lottie/lottieitem.cpp:839
    No locals.
    #6  0x00007ffff7f5ab61 in rlottie::internal::renderer::Layer::update (this=0x555555574218, frameNumber=0, parentMatrix=..., parentAlpha=1) at ./src/lottie/lottieitem.cpp:430
            alpha = 1
            m = {m11 = inf, m12 = 0, m13 = 0, m21 = 0, m22 = inf, m23 = 0, mtx = -nan(0x400000), mty = -nan(0x400000), m33 = 1, mType = VMatrix::MatrixType::Scale, dirty = VMatrix::MatrixType::None}
    #7  0x00007ffff7f5bdf5 in rlottie::internal::renderer::CompLayer::updateContent (this=0x555555574190) at ./src/lottie/lottieitem.cpp:653
            layer = @0x555555574990: 0x555555574218
            __for_range = std::vector of length 1, capacity 1 = {0x555555574218}
            __for_begin = 0x555555574218
            __for_end = 0x7ffff7cad290 <main_arena+1584>
            mappedFrame = 0
            alpha = 1
    #8  0x00007ffff7f5ab61 in rlottie::internal::renderer::Layer::update (this=0x555555574190, frameNumber=0, parentMatrix=..., parentAlpha=1) at ./src/lottie/lottieitem.cpp:430
            alpha = 1
            m = {m11 = inf, m12 = 0, m13 = 0, m21 = 0, m22 = inf, m23 = 0, mtx = -nan(0x400000), mty = -nan(0x400000), m33 = 1, mType = VMatrix::MatrixType::Scale, dirty = VMatrix::MatrixType::None}
    #9  0x00007ffff7f592f2 in rlottie::internal::renderer::Composition::update (this=0x555555574070, frameNo=0, size=..., keepAspectRatio=true) at ./src/lottie/lottieitem.cpp:146
            m = {m11 = inf, m12 = 0, m13 = 0, m21 = 0, m22 = inf, m23 = 0, mtx = -nan(0x400000), mty = -nan(0x400000), m33 = 1, mType = VMatrix::MatrixType::Scale, dirty = VMatrix::MatrixType::None}
            viewPort = {mw = 200, mh = 200}
            viewBox = {mw = 0, mh = 0}
            sx = inf
            sy = inf
    #10 0x00007ffff7fa9e7a in AnimationImpl::update (this=0x555555573500, frameNo=0, size=..., keepAspectRatio=true) at ./src/lottie/lottieanimation.cpp:105
    No locals.
    #11 0x00007ffff7fa9f91 in AnimationImpl::render (this=0x555555573500, frameNo=0, surface=..., keepAspectRatio=true) at ./src/lottie/lottieanimation.cpp:118
            renderInProgress = false
    #12 0x00007ffff7faaaf4 in rlottie::Animation::renderSync (this=0x555555573550, frameNo=0, surface=..., keepAspectRatio=true) at ./src/lottie/lottieanimation.cpp:371
    No locals.
    #13 0x000055555555b301 in App::render (this=0x7fffffffd9c0, w=200, h=200) at ./example/lottie2gif.cpp:91
            surface = {mBuffer = 0x7ffff7983010, mWidth = 200, mHeight = 200, mBytesPerLine = 800, mDrawArea = {x = 0, y = 0, w = 200, h = 200}}
            i = 0
            player = std::unique_ptr<rlottie::Animation> = {get() = {<No data fields>}}
            buffer = std::unique_ptr<unsigned int []> = {get() = {<No data fields>}}
            frameCount = 1
            builder = {handle = {f = 0x555555573320, oldImage = 0x7ffff795b010 "", firstFrame = true}, bgColorR = 255 '\377', bgColorG = 255 '\377', bgColorB = 255 '\377'}
    #14 0x000055555555ac35 in main (argc=2, argv=0x7fffffffdb48) at ./example/lottie2gif.cpp:175
            app = {bgColor = -1, fileName = "/home/mymedia/rlottie/fuzz/collect/002f.json", gifName = "002f.json.gif"}
            w = 200
            h = 200
    #15 0x00007ffff7ac1fd0 in __libc_start_call_main ([email protected]=0x55555555abbe <main(int, char**)>, [email protected]=2, [email protected]=0x7fffffffdb48) at ../sysdeps/nptl/libc_start_call_main.h:58
            self = <optimized out>
            result = <optimized out>
            unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, -5304380250038046668, 140737488345928, 93824992259006, 0, 140737354120256, 5304380248853737524, 5304361971744665652}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x10000ffff, 0x7fffffffdac0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 65535}}}
            not_first_call = <optimized out>
    #16 0x00007ffff7ac207d in __libc_start_main_impl (main=0x55555555abbe <main(int, char**)>, argc=2, argv=0x7fffffffdb48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdb38) at ../csu/libc-start.c:409
    No locals.
    #17 0x00005555555585a5 in _start ()
    No symbol table info available.
    

    Cases 3, 4, 5

    Stack overflow on cyclic structures. 009f.json {"v":"0","assets":[{"id":"a","layers":[{"ks":{},"ty":0,"refId":"a"}]}],"layers":[{"ks":{},"ty":0,"refId":"a"}]} 010f.json {"v":"0","assets":[{"id":"b","layers":[{"ks":{},"ty":0,"refId":"b"}]}],"layers":[{"ks":{}},{"ks":{},"ty":0,"refId":"b"}]} 011f.json {"v":"0","assets":[{"id":"c","layers":[{"ks":{},"ty":0,"refId":"c"}]}],"layers":[{"ks":{},"ty":0,"refId":"c"},{"ks":{},"ty":0,"refId":""}]} (Sorry for gaps between file numbers. I tried to minimize other samples but they seem irrelevant).

    Click to see output (gdb ...)
    [email protected]:~/rlottie$ gdb -ex run -ex bt\ full\ -20 -ex q --args build/example/lottie2gif fuzz/collect/009f.json
    Reading symbols from build/example/lottie2gif...
    Starting program: /home/mymedia/rlottie/build/example/lottie2gif fuzz/collect/009f.json
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    
    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff7f7ea48 in std::vector<rlottie::internal::model::Object*, std::allocator<rlottie::internal::model::Object*> >::end (this=<error reading variable: Cannot access memory at address 0x7fffff7feff8>) at /usr/include/c++/11/bits/stl_vector.h:829
    829           end() _GLIBCXX_NOEXCEPT
    #104755 0x00007ffff7f7e180 in LottieRepeaterProcesser::visit (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:85
    No locals.
    #104756 0x00007ffff7f7e0e7 in LottieRepeaterProcesser::visitChildren (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:76
            child = 0x5555555737e8
            i = {<std::iterator<std::random_access_iterator_tag, rlottie::internal::model::Object*, long, rlottie::internal::model::Object**, rlottie::internal::model::Object*&>> = {<No data fields>}, current = 0x7ffff7caccc0 <main_arena+96>}
    #104757 0x00007ffff7f7e180 in LottieRepeaterProcesser::visit (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:85
    No locals.
    #104758 0x00007ffff7f7e0e7 in LottieRepeaterProcesser::visitChildren (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:76
            child = 0x5555555737e8
            i = {<std::iterator<std::random_access_iterator_tag, rlottie::internal::model::Object*, long, rlottie::internal::model::Object**, rlottie::internal::model::Object*&>> = {<No data fields>}, current = 0x7ffff7caccc0 <main_arena+96>}
    #104759 0x00007ffff7f7e180 in LottieRepeaterProcesser::visit (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:85
    No locals.
    #104760 0x00007ffff7f7e0e7 in LottieRepeaterProcesser::visitChildren (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:76
            child = 0x5555555737e8
            i = {<std::iterator<std::random_access_iterator_tag, rlottie::internal::model::Object*, long, rlottie::internal::model::Object**, rlottie::internal::model::Object*&>> = {<No data fields>}, current = 0x7ffff7caccc0 <main_arena+96>}
    #104761 0x00007ffff7f7e180 in LottieRepeaterProcesser::visit (this=0x7fffffffd317, obj=0x5555555737e8) at ./src/lottie/lottiemodel.cpp:85
    No locals.
    #104762 0x00007ffff7f7e0e7 in LottieRepeaterProcesser::visitChildren (this=0x7fffffffd317, obj=0x555555573970) at ./src/lottie/lottiemodel.cpp:76
            child = 0x5555555737e8
            i = {<std::iterator<std::random_access_iterator_tag, rlottie::internal::model::Object*, long, rlottie::internal::model::Object**, rlottie::internal::model::Object*&>> = {<No data fields>}, current = 0x7ffff7caccc0 <main_arena+96>}
    #104763 0x00007ffff7f7e180 in LottieRepeaterProcesser::visit (this=0x7fffffffd317, obj=0x555555573970) at ./src/lottie/lottiemodel.cpp:85
    No locals.
    #104764 0x00007ffff7f7e0e7 in LottieRepeaterProcesser::visitChildren (this=0x7fffffffd317, obj=0x555555573900) at ./src/lottie/lottiemodel.cpp:76
            child = 0x555555573970
            i = {<std::iterator<std::random_access_iterator_tag, rlottie::internal::model::Object*, long, rlottie::internal::model::Object**, rlottie::internal::model::Object*&>> = {<No data fields>}, current = 0x0}
    #104765 0x00007ffff7f7e180 in LottieRepeaterProcesser::visit (this=0x7fffffffd317, obj=0x555555573900) at ./src/lottie/lottiemodel.cpp:85
    No locals.
    #104766 0x00007ffff7f7bff4 in rlottie::internal::model::Composition::processRepeaterObjects (this=0x555555573690) at ./src/lottie/lottiemodel.cpp:152
            visitor = {<No data fields>}
    #104767 0x00007ffff7f8a8d5 in rlottie::internal::model::parse(char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::function<void (float&, float&, float&)>) (str=0x555555575510 "{\"v", dir_path="", filter=...) at ./src/lottie/lottieparser.cpp:2378
            composition = std::shared_ptr<rlottie::internal::model::Composition> (use count 2, weak count 0) = {get() = 0x555555573690}
            obj = {<LookaheadParserHandler> = {v_ = {data_ = {s = {length = 1, hashcode = 0, str = 0x40555555557557a <error: Cannot access memory at address 0x40555555557557a>}, ss = {str = "\001\000\000\000\000\000\000\000zUWUUU"}, n = {i = {i = 1, padding = "\000\000\000"}, u = {u = 1, padding2 = "\000\000\000"}, i64 = 1, u64 = 1, d = 4.9406564584124654e-324}, o = {size = 1, capacity = 0, members = 0x40555555557557a}, a = {size = 1, capacity = 0, elements = 0x40555555557557a}, f = {payload = "\001\000\000\000\000\000\000\000zUWUUU", flags = 1029}}}, st_ = LookaheadParserHandler::kExitingObject, r_ = {static kDefaultStackCapacity = 256, stack_ = {allocator_ = 0x555555573550, ownAllocator_ = 0x555555573550, stack_ = 0x555555573570 "\002", stackTop_ = 0x555555573570 "\002", stackEnd_ = 0x555555573670 "", initialCapacity_ = 256}, parseResult_ = {code_ = rapidjson::kParseErrorNone, offset_ = 0}, state_ = rapidjson::GenericReader<rapidjson::UTF8<char>, rapidjson::UTF8<char>, rapidjson::CrtAllocator>::IterativeParsingFinishState}, ss_ = {src_ = 0x555555575580 "", dst_ = 0x55555557557c "}]}\n", head_ = 0x555555575510 "{\"v"}, static parseFlags = 1}, mColorFilter = {<std::_Maybe_unary_or_binary_function<void, float&, float&, float&>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16, static _M_max_align = 8, _M_functor = {_M_unused = {_M_object = 0x0, _M_const_object = 0x0, _M_function_pointer = 0x0, _M_member_pointer = NULL}, _M_pod_data = '\000' <repeats 15 times>}, _M_manager = 0x0}, _M_invoker = 0x0}, mPathInfo = {mInPoint = std::vector of length 0, capacity 0, mOutPoint = std::vector of length 0, capacity 0, mVertices = std::vector of length 0, capacity 0, mResult = std::vector of length 0, capacity 0, mClosed = false}, mInterpolatorCache = std::unordered_map with 0 elements, mComposition = std::shared_ptr<rlottie::internal::model::Composition> (use count 2, weak count 0) = {get() = 0x555555573690}, compRef = 0x555555573690, curLayerRef = 0x555555573970, mLayersToUpdate = std::vector of length 2, capacity 2 = {0x5555555737e8, 0x555555573970}, mDirPath = "/home/mymedia/rlottie/fuzz/collect/"}
    #104768 0x00007ffff7f7b877 in rlottie::internal::model::loadFromFile (path="/home/mymedia/rlottie/fuzz/collect/009f.json", cachePolicy=true) at ./src/lottie/lottieloader.cpp:139
            content = "{\"v\000:\"0\000,\"assets\000:[{\"id\000:\"a\000,\"layers\000:[{\"ks\000:{},\"ty\000:0,\"refId\000:\"a\000}]}],\"layers\000:[{\"ks\000:{},\"ty\000:0,\"refId\000:\"a\000}]}\n"
            obj = std::shared_ptr<rlottie::internal::model::Composition> (empty) = {get() = 0x0}
            f = <incomplete type>
    #104769 0x00007ffff7faa776 in rlottie::Animation::loadFromFile (path="/home/mymedia/rlottie/fuzz/collect/009f.json", cachePolicy=true) at ./src/lottie/lottieanimation.cpp:319
            composition = std::shared_ptr<rlottie::internal::model::Composition> (empty) = {get() = 0x0}
    #104770 0x000055555555b150 in App::render (this=0x7fffffffd9c0, w=200, h=200) at ./example/lottie2gif.cpp:82
            player = std::unique_ptr<rlottie::Animation> = {get() = {<No data fields>}}
            buffer = std::unique_ptr<unsigned int []> = {get() = {<No data fields>}}
            frameCount = 140737353009600
            builder = {handle = {f = 0x7ffff7eeca60, oldImage = 0x7ffff7eedb00 "@\327\356\367\377\177", firstFrame = 176}, bgColorR = 32 ' ', bgColorG = 6 '\006', bgColorB = 252 '\374'}
    #104771 0x000055555555ac35 in main (argc=2, argv=0x7fffffffdb48) at ./example/lottie2gif.cpp:175
            app = {bgColor = -1, fileName = "/home/mymedia/rlottie/fuzz/collect/009f.json", gifName = "009f.json.gif"}
            w = 200
            h = 200
    #104772 0x00007ffff7ac1fd0 in __libc_start_call_main ([email protected]=0x55555555abbe <main(int, char**)>, [email protected]=2, [email protected]=0x7fffffffdb48) at ../sysdeps/nptl/libc_start_call_main.h:58
            self = <optimized out>
            result = <optimized out>
            unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, 2290260297761485036, 140737488345928, 93824992259006, 0, 140737354120256, -2290260296781729556, -2290277483006856980}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x10000ffff, 0x7fffffffdac0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 65535}}}
            not_first_call = <optimized out>
    #104773 0x00007ffff7ac207d in __libc_start_main_impl (main=0x55555555abbe <main(int, char**)>, argc=2, argv=0x7fffffffdb48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdb38) at ../csu/libc-start.c:409
    No locals.
    #104774 0x00005555555585a5 in _start ()
    No symbol table info available.
    

    Case 6

    Stack overflow at VBezier::length(). 013f.json {"v":"0","op":9,"layers":[{"ty":4,"ks":{},"shapes":[{"ty":"gr","it":[{"ty":"sh","ks":{"k":{"i":[[],[]],"o":[[0,2000000000],[]],"v":[[],[1200000]]}}}]},{"ty":"tm","s":{"k":[{"i":{},"s":[100]},{"t":9}]}}],"op":9}]}

    Click to see output (gdb ...)
    [email protected]:~/rlottie$ gdb -ex run -ex bt\ full\ -40 -ex q --args build/example/lottie2gif fuzz/collect/013f.json
    Reading symbols from build/example/lottie2gif...
    Starting program: /home/mymedia/rlottie/build/example/lottie2gif fuzz/collect/013f.json
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    
    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff7f51a94 in VBezier::split (this=<error reading variable: Cannot access memory at address 0x7fffff7feff8>, firstHalf=<error reading variable: Cannot access memory at address 0x7fffff7feff0>, secondHalf=<error reading variable: Cannot access memory at address 0x7fffff7fefe8>) at ./src/vector/vbezier.h:117
    117     {
    #37396 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc240) at ./src/vector/vbezier.cpp:55
            left = {x1 = 311053.438, y1 = 888888832, x2 = 311054.688, y2 = 888888832, x3 = 311055.938, y3 = 888888832, x4 = 311057.188, y4 = 888888832}
            right = {x1 = 311057.188, y1 = 888888832, x2 = 311058.438, y2 = 888888832, x3 = 311059.688, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            len = 69.96875
            chord = 66.8242188
    #37397 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc320) at ./src/vector/vbezier.cpp:55
            left = {x1 = 311045.938, y1 = 888888832, x2 = 311048.438, y2 = 888888832, x3 = 311050.938, y3 = 888888832, x4 = 311053.438, y4 = 888888832}
            right = {x1 = 311053.438, y1 = 888888832, x2 = 311055.938, y2 = 888888832, x3 = 311058.438, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            len = 75.90625
            chord = 69.6367188
    #37398 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc400) at ./src/vector/vbezier.cpp:55
            left = {x1 = 311030.938, y1 = 888888832, x2 = 311035.938, y2 = 888888832, x3 = 311040.938, y3 = 888888832, x4 = 311045.938, y4 = 888888832}
            right = {x1 = 311045.938, y1 = 888888832, x2 = 311050.938, y2 = 888888832, x3 = 311055.938, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            len = 87.78125
            chord = 75.2617188
    #37399 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc4e0) at ./src/vector/vbezier.cpp:55
            left = {x1 = 311000.906, y1 = 888888832, x2 = 311010.938, y2 = 888888832, x3 = 311020.938, y3 = 888888832, x4 = 311030.938, y4 = 888888832}
            right = {x1 = 311030.938, y1 = 888888832, x2 = 311040.938, y2 = 888888832, x3 = 311050.938, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            len = 111.5625
            chord = 86.5234375
    #37400 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc5c0) at ./src/vector/vbezier.cpp:55
            left = {x1 = 310940.812, y1 = 888888832, x2 = 310960.844, y2 = 888888832, x3 = 310980.875, y3 = 888888832, x4 = 311000.906, y4 = 888888832}
            right = {x1 = 311000.906, y1 = 888888832, x2 = 311020.938, y2 = 888888832, x3 = 311040.938, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            len = 159.117188
            chord = 144.15625
    #37401 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc680) at ./src/vector/vbezier.cpp:55
            left = {x1 = 310820.688, y1 = 888888704, x2 = 310860.75, y2 = 888888768, x3 = 310900.781, y3 = 888888832, x4 = 310940.812, y4 = 888888832}
            right = {x1 = 310940.812, y1 = 888888832, x2 = 310980.875, y2 = 888888832, x3 = 311020.938, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            len = 342.222656
            chord = 312.28125
    #37402 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffc780) at ./src/vector/vbezier.cpp:55
            left = {x1 = 310820.688, y1 = 888888704, x2 = 310900.781, y2 = 888888832, x3 = 310980.875, y3 = 888888896, x4 = 311060.969, y4 = 888888896}
            right = {x1 = 311060.969, y1 = 888888896, x2 = 311141.062, y2 = 888888896, x3 = 311221.188, y3 = 888888832, x4 = 311301.312, y4 = 888888768}
            len = 688.351562
            chord = 504.625
    #37403 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffc840) at ./src/vector/vbezier.cpp:55
            left = {x1 = 310340.281, y1 = 888887488, x2 = 310500.375, y2 = 888888064, x3 = 310660.531, y3 = 888888448, x4 = 310820.688, y4 = 888888704}
            right = {x1 = 310820.688, y1 = 888888704, x2 = 310980.875, y2 = 888888896, x3 = 311141.062, y3 = 888888960, x4 = 311301.312, y4 = 888888768}
            len = 2280.67969
            chord = 1640.38672
    #37404 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffc940) at ./src/vector/vbezier.cpp:55
            left = {x1 = 310340.281, y1 = 888887488, x2 = 310660.5, y2 = 888888640, x3 = 310980.844, y3 = 888889088, x4 = 311301.312, y4 = 888888768}
            right = {x1 = 311301.312, y1 = 888888768, x2 = 311621.812, y2 = 888888448, x3 = 311942.469, y3 = 888887488, x4 = 312263.25, y4 = 888885760}
            len = 7097.73828
            chord = 2570.96875
    #37405 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffca00) at ./src/vector/vbezier.cpp:55
            left = {x1 = 308420.844, y1 = 888871872, x2 = 309060.062, y2 = 888880000, x3 = 309699.875, y3 = 888885184, x4 = 310340.281, y4 = 888887488}
            right = {x1 = 310340.281, y1 = 888887488, x2 = 310980.688, y2 = 888889792, x3 = 311621.688, y3 = 888889216, x4 = 312263.25, y4 = 888885760}
            len = 29152.9023
            chord = 15328.9023
    #37406 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffcb00) at ./src/vector/vbezier.cpp:55
            left = {x1 = 308420.844, y1 = 888871872, x2 = 309699.312, y2 = 888888064, x3 = 310980.125, y3 = 888892672, x4 = 312263.25, y4 = 888885760}
            right = {x1 = 312263.25, y1 = 888885760, x2 = 313546.375, y2 = 888878912, x3 = 314831.781, y3 = 888860480, x4 = 316119.469, y4 = 888830592}
            len = 109062.984
            chord = 44166.9844
    #37407 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffcbc0) at ./src/vector/vbezier.cpp:55
            left = {x1 = 300778.188, y1 = 888634496, x2 = 303316.219, y2 = 888760512, x3 = 305863.875, y3 = 888839424, x4 = 308420.844, y4 = 888871872}
            right = {x1 = 308420.844, y1 = 888871872, x2 = 310977.812, y2 = 888904320, x3 = 313544.094, y3 = 888890368, x4 = 316119.469, y4 = 888830592}
            len = 440825
            chord = 201848.984
    #37408 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffccc0) at ./src/vector/vbezier.cpp:55
            left = {x1 = 300778.188, y1 = 888634496, x2 = 305854.25, y2 = 888886528, x3 = 310968.719, y3 = 888950080, x4 = 316119.469, y4 = 888830592}
            right = {x1 = 316119.469, y1 = 888830592, x2 = 321270.219, y2 = 888711040, x3 = 326457.25, y3 = 888408448, x4 = 331678.406, y4 = 887928064}
            len = 1726019.62
            chord = 718019.562
    #37409 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffcd80) at ./src/vector/vbezier.cpp:55
            left = {x1 = 270799.688, y1 = 884818944, x2 = 280627.531, y2 = 886872896, x3 = 290626.062, y3 = 888130560, x4 = 300778.188, y4 = 888634496}
            right = {x1 = 300778.188, y1 = 888634496, x2 = 310930.312, y2 = 889138496, x3 = 321236.094, y3 = 888888832, x4 = 331678.406, y4 = 887928064}
            len = 6974894
            chord = 3131949.5
    #37410 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffce60) at ./src/vector/vbezier.cpp:55
            left = {x1 = 270799.688, y1 = 884818944, x2 = 290455.375, y2 = 888926848, x3 = 310793.781, y3 = 889849536, x4 = 331678.406, y4 = 887928064}
            right = {x1 = 331678.406, y1 = 887928064, x2 = 352563.031, y2 = 886006592, x3 = 373993.875, y3 = 881240960, x4 = 395834.5, y4 = 873972288}
            len = 27325288
            chord = 10893544
    #37411 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffcf40) at ./src/vector/vbezier.cpp:55
            left = {x1 = 270799.688, y1 = 884818944, x2 = 310111.094, y2 = 893034816, x3 = 352153.25, y3 = 888509568, x4 = 395834.5, y4 = 873972288}
            right = {x1 = 395834.5, y1 = 873972288, x2 = 439515.781, y2 = 859435008, x3 = 484836.188, y3 = 834885568, x4 = 530704.125, y4 = 803053056}
            len = 114726840
            chord = 81863352
    #37412 0x00007ffff7f51072 in VBezier::length (this=0x7fffffffd040) at ./src/vector/vbezier.cpp:55
            left = {x1 = 270799.688, y1 = 884818944, x2 = 349422.5, y2 = 901250688, x3 = 438968.25, y3 = 866718080, x4 = 530704.125, y4 = 803053056}
            right = {x1 = 530704.125, y1 = 803053056, x2 = 622440, y2 = 739387968, x3 = 716366, y3 = 646590528, x4 = 803749.375, y4 = 546492672}
            len = 404253088
            chord = 338526144
    #37413 0x00007ffff7f51086 in VBezier::length (this=0x7fffffffd0d0) at ./src/vector/vbezier.cpp:55
            left = {x1 = 0, y1 = 0, x2 = 0, y2 = 615234368, x3 = 113554, y3 = 851955456, x4 = 270799.688, y4 = 884818944}
            right = {x1 = 270799.688, y1 = 884818944, x2 = 428045.344, y2 = 917682432, x3 = 628982.688, y3 = 746688384, x4 = 803749.375, y4 = 546492672}
            len = 1.91474611e+09
            chord = 546794048
    #37414 0x00007ffff7f512e2 in VBezier::tAtLength (this=0x7fffffffd1d0, l=1.58064678e+09, totalLength=1.77822771e+09) at ./src/vector/vbezier.cpp:88
            right = {x1 = 803749.375, y1 = 546492672, x2 = 1022346.5, y2 = 296089184, x3 = 1200000, y3 = 0, x4 = 1200000, y4 = 0}
            left = {x1 = 0, y1 = 0, x2 = 0, y2 = 1.23046874e+09, x3 = 454216, y3 = 946884160, x4 = 803749.375, y4 = 546492672}
            lLen = 921744320
            num = 8
            t = 0.615234375
            error = 0.00999999978
            lastBigger = 0.8203125
    #37415 0x00007ffff7f517e4 in VBezier::tAtLength (this=0x7fffffffd1d0, len=1.58064678e+09) at ./src/vector/vbezier.h:42
    No locals.
    #37416 0x00007ffff7f5140a in VBezier::splitAtLength (this=0x7fffffffd1f0, len=1.58064678e+09, left=0x7fffffffd1b0, right=0x7fffffffd1d0) at ./src/vector/vbezier.cpp:107
            t = 3802.08179
    #37417 0x00007ffff7f2d843 in VDasher::cubicTo (this=0x7fffffffd320, cp1=..., cp2=..., e=...) at ./src/vector/vdasher.cpp:172
            left = {x1 = -nan(0x7fd1d0), y1 = 4.59163468e-41, x2 = -9.85034955e+33, y2 = 4.59163468e-41, x3 = -nan(0x7fd200), y3 = 4.59163468e-41, x4 = -nan(0x7fd320), y4 = 4.59163468e-41}
            right = {x1 = 0, y1 = 0, x2 = 0, y2 = 2e+09, x3 = 1200000, y3 = 0, x4 = 1200000, y4 = 0}
            b = {x1 = 0, y1 = 0, x2 = 0, y2 = 2e+09, x3 = 1200000, y3 = 0, x4 = 1200000, y4 = 0}
            bezLen = 197580928
    #37418 0x00007ffff7f2db7b in VDasher::dashHelper (this=0x7fffffffd320, path=..., result=...) at ./src/vector/vdasher.cpp:212
            i = @0x555555574b51: VPath::Element::CubicTo
            __for_range = std::vector of length 2, capacity 3 = {VPath::Element::MoveTo, VPath::Element::CubicTo}
            __for_begin = VPath::Element::CubicTo
            __for_end = 85
            elms = std::vector of length 2, capacity 3 = {VPath::Element::MoveTo, VPath::Element::CubicTo}
            pts = std::vector of length 4, capacity 5 = {{mx = 0, my = 0}, {mx = 0, my = 2e+09}, {mx = 1200000, my = 0}, {mx = 1200000, my = 0}}
            ptPtr = 0x555555574098
    #37419 0x00007ffff7f2dc90 in VDasher::dashed (this=0x7fffffffd320, path=..., result=...) at ./src/vector/vdasher.cpp:236
    No locals.
    #37420 0x00007ffff7f4c321 in VPathMesure::trim (this=0x5555555744f8, path=...) at ./src/vector/vpathmesure.cpp:53
            array = {0, 0, 1.58064678e+09, 3.40282347e+38}
            dasher = {mDashArray = 0x7fffffffd360, mArraySize = 2, mCurPt = {mx = 0, my = 0}, mIndex = 1, mCurrentLength = 1.58064678e+09, mDashOffset = 0, mResult = 0x555555574500, mDiscard = false, mStartNewSegment = true, mNoLength = false, mNoGap = false}
            length = 1.77822771e+09
    #37421 0x00007ffff7f5f77a in rlottie::internal::renderer::Trim::update (this=0x5555555744c0) at ./src/lottie/lottieitem.cpp:1386
            i = @0x555555574b70: 0x555555574578
            __for_range = std::vector of length 1, capacity 1 = {0x555555574578}
            __for_begin = 0x555555574578
            __for_end = 0x7ffff7caccc0 <main_arena+96>
    #37422 0x00007ffff7f5d978 in rlottie::internal::renderer::Group::applyTrim (this=0x555555574460) at ./src/lottie/lottieitem.cpp:981
            content = 0x5555555744c0
            i = {<std::iterator<std::random_access_iterator_tag, rlottie::internal::renderer::Object*, long, rlottie::internal::renderer::Object**, rlottie::internal::renderer::Object*&>> = {<No data fields>}, current = 0x555555574518}
    #37423 0x00007ffff7f5cb62 in rlottie::internal::renderer::ShapeLayer::updateContent (this=0x5555555743d8) at ./src/lottie/lottieitem.cpp:842
    No locals.
    #37424 0x00007ffff7f5ab61 in rlottie::internal::renderer::Layer::update (this=0x5555555743d8, frameNumber=1, parentMatrix=..., parentAlpha=1) at ./src/lottie/lottieitem.cpp:430
            alpha = 1
            m = {m11 = inf, m12 = 0, m13 = 0, m21 = 0, m22 = inf, m23 = 0, mtx = -nan(0x400000), mty = -nan(0x400000), m33 = 1, mType = VMatrix::MatrixType::Scale, dirty = VMatrix::MatrixType::None}
    #37425 0x00007ffff7f5bdf5 in rlottie::internal::renderer::CompLayer::updateContent (this=0x555555574350) at ./src/lottie/lottieitem.cpp:653
            layer = @0x555555574010: 0x5555555743d8
            __for_range = std::vector of length 1, capacity 1 = {0x5555555743d8}
            __for_begin = 0x5555555743d8
            __for_end = 0x0
            mappedFrame = 1
            alpha = 1
    #37426 0x00007ffff7f5ab61 in rlottie::internal::renderer::Layer::update (this=0x555555574350, frameNumber=1, parentMatrix=..., parentAlpha=1) at ./src/lottie/lottieitem.cpp:430
            alpha = 1
            m = {m11 = inf, m12 = 0, m13 = 0, m21 = 0, m22 = inf, m23 = 0, mtx = -nan(0x400000), mty = -nan(0x400000), m33 = 1, mType = VMatrix::MatrixType::Scale, dirty = VMatrix::MatrixType::None}
    #37427 0x00007ffff7f592f2 in rlottie::internal::renderer::Composition::update (this=0x555555574230, frameNo=1, size=..., keepAspectRatio=true) at ./src/lottie/lottieitem.cpp:146
            m = {m11 = inf, m12 = 0, m13 = 0, m21 = 0, m22 = inf, m23 = 0, mtx = -nan(0x400000), mty = -nan(0x400000), m33 = 1, mType = VMatrix::MatrixType::Scale, dirty = VMatrix::MatrixType::None}
            viewPort = {mw = 200, mh = 200}
            viewBox = {mw = 0, mh = 0}
            sx = inf
            sy = inf
    #37428 0x00007ffff7fa9e7a in AnimationImpl::update (this=0x555555573500, frameNo=1, size=..., keepAspectRatio=true) at ./src/lottie/lottieanimation.cpp:105
    No locals.
    #37429 0x00007ffff7fa9f91 in AnimationImpl::render (this=0x555555573500, frameNo=1, surface=..., keepAspectRatio=true) at ./src/lottie/lottieanimation.cpp:118
            renderInProgress = false
    #37430 0x00007ffff7faaaf4 in rlottie::Animation::renderSync (this=0x555555573550, frameNo=1, surface=..., keepAspectRatio=true) at ./src/lottie/lottieanimation.cpp:371
    No locals.
    #37431 0x000055555555b301 in App::render (this=0x7fffffffd9c0, w=200, h=200) at ./example/lottie2gif.cpp:91
            surface = {mBuffer = 0x7ffff7983010, mWidth = 200, mHeight = 200, mBytesPerLine = 800, mDrawArea = {x = 0, y = 0, w = 200, h = 200}}
            i = 1
            player = std::unique_ptr<rlottie::Animation> = {get() = {<No data fields>}}
            buffer = std::unique_ptr<unsigned int []> = {get() = {<No data fields>}}
            frameCount = 9
            builder = {handle = {f = 0x555555573320, oldImage = 0x7ffff795b010 '\377' <repeats 200 times>..., firstFrame = false}, bgColorR = 255 '\377', bgColorG = 255 '\377', bgColorB = 255 '\377'}
    #37432 0x000055555555ac35 in main (argc=2, argv=0x7fffffffdb48) at ./example/lottie2gif.cpp:175
            app = {bgColor = -1, fileName = "/home/mymedia/rlottie/fuzz/collect/013f.json", gifName = "013f.json.gif"}
            w = 200
            h = 200
    #37433 0x00007ffff7ac1fd0 in __libc_start_call_main ([email protected]=0x55555555abbe <main(int, char**)>, [email protected]=2, [email protected]=0x7fffffffdb48) at ../sysdeps/nptl/libc_start_call_main.h:58
            self = <optimized out>
            result = <optimized out>
            unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, 2056828669123042546, 140737488345928, 93824992259006, 0, 140737354120256, -2056828667890295566, -2056810639910298382}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x10000ffff, 0x7fffffffdac0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 65535}}}
            not_first_call = <optimized out>
    #37434 0x00007ffff7ac207d in __libc_start_main_impl (main=0x55555555abbe <main(int, char**)>, argc=2, argv=0x7fffffffdb48, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdb38) at ../csu/libc-start.c:409
    No locals.
    #37435 0x00005555555585a5 in _start ()
    No symbol table info available.
    
  • JSON license could be removed

    JSON license could be removed

    The only files using this license in rapidjson repository are bin/jsonchecker/*.json files. Since they are not present here, this controversial license can be dropped.

  • Can't build rlottie with static linking using MinGW

    Can't build rlottie with static linking using MinGW

    Hi!

    It's not possible to build rlottie with static linking on Windows when compiled using MinGW.

    There is a minor issue in the CMakeLists.txt file where the following lines makes the configuration fail: if (WIN32 AND NOT BUILD_SHARED_LIBS) target_compile_definitions(rlottie PUBLIC -DRLOTTIE_BUILD=0) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") endif()

    These are MSVC flags and MinGW of course can't interpret them as it needs GCC-style compiler flags.

    This is a minor thing though, more serious is that there are multiple linker issues when linking against librlottie.a The issue is present on the master branch (latest commit 875626965959d8e269ca22175c8e1ad190696c43).

    I'm attaching an output of the errors: MinGW_linking_errors.txt

    Many thanks in advance!

  • On Windows rlottie hangs (forever) on application shutdown when compiled with MinGW

    On Windows rlottie hangs (forever) on application shutdown when compiled with MinGW

    Hi!

    If rlottie is compiled using MinGW 9.2.0 then the application will hang (seemingly forever) on shutdown if either render() or renderSync() has been called at least one.

    This problem does not occur when compiled using MSVC but unfortunately I need to use MinGW for my release builds so that's not a solution for me.

    I have also not seen the issue on any of the other operating systems that I've built rlottie on (macOS, Linux, FreeBSD, NetBSD and OpenBSD).

    This issue is present on the master branch with the latest commit 875626965959d8e269ca22175c8e1ad190696c43. I have compiled as shared library/DLL and apart from the hang on shutdown, everything seems to work fine with correct rendering and equivalent performance compared to other platforms.

    Many thanks in advance!

Related tags
ORE (OpenGL Rendering Engine) is a rendering engine developed for my college minor project assessment.
ORE (OpenGL Rendering Engine) is a rendering engine developed for my college minor project assessment.

ORE (OPENGL RENDERING ENGINE) What is ORE? ORE(OpenGL Rendering Engine) is a rendering engine with great and easy to use UI that allows the user to lo

Dec 20, 2021
A realtime Vulkan voxel path tracer.
A realtime Vulkan voxel path tracer.

brickmap-vulkan A realtime Vulkan voxel path tracer. This is a work in progress! This system is a Vulkan/SPIRV implementation of the BrickMap by stijn

Jun 12, 2022
A modern cross-platform low-level graphics library and rendering framework
A modern cross-platform low-level graphics library and rendering framework

Diligent Engine A Modern Cross-Platform Low-Level 3D Graphics Library Diligent Engine is a lightweight cross-platform graphics API abstraction library

Jun 17, 2022
Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.
Cross-platform, graphics API agnostic,

bgfx - Cross-platform rendering library GitHub Discussions Discord Chat What is it? Cross-platform, graphics API agnostic, "Bring Your Own Engine/Fram

Jun 22, 2022
Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.

This project is not actively maintained. NanoVG NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled afte

Jun 19, 2022
LibGizmo is a small, standalone library that adds a 3D matrix (4x4 floats) manipulation control called 'Gizmo'

LibGizmo is a small, standalone library that adds a 3D matrix (4x4 floats) manipulation control called 'Gizmo'

Jun 9, 2022
SoL (for Speed of Light, or sun in Spanish) is a Physically-based rendering library written in modern C++

SoL (for Speed of Light, or sun in Spanish) is a small rendering library written in C++20. Its goal is to strike a good balance between performance and usability, and allow easy experimentation for rendering researchers.

May 19, 2022
A standalone Dear ImGui node graph implementation.
A standalone Dear ImGui node graph implementation.

ImNodes A standalone Dear ImGui node graph implementation. Library provides core features needed to create a node graph, while leaving it to the user

Jun 9, 2022
2D Vector Graphics Engine Powered by a JIT Compiler

Blend2D 2D Vector Graphics Powered by a JIT Compiler. Official Home Page (blend2d.com) Official Repository (blend2d/blend2d) Public Chat Channel Zlib

Jun 16, 2022
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.

pbrt, Version 3 This repository holds the source code to the version of pbrt that is described in the third edition of Physically Based Rendering: Fro

Jun 22, 2022
appleseed is an open source, physically-based global illumination rendering engine primarily designed for animation and visual effects.
appleseed is an open source, physically-based global illumination rendering engine primarily designed for animation and visual effects.

appleseed is an open source, physically-based global illumination rendering engine primarily designed for animation and visual effects.

Jun 21, 2022
Source Code for "Ray Tracing Gems: High-Quality and Real-Time Rendering with DXR and Other APIs" by Eric Haines and Tomas Akenine-MΓΆller

Apress Source Code This repository accompanies Ray Tracing Gems: High-Quality and Real-Time Rendering with DXR and Other APIs by Eric Haines and Tomas

Jun 15, 2022
Single header C library for rendering truetype text to the screen
Single header C library for rendering truetype text to the screen

kc_truetypeassembler.h Single header C library for assembling textured quads for text rendering using a graphics API. It generates a vertices and text

Jun 15, 2022
NVRHI (NVIDIA Rendering Hardware Interface) is a library that implements a common abstraction layer over multiple graphics APIs

NVRHI Introduction NVRHI (NVIDIA Rendering Hardware Interface) is a library that implements a common abstraction layer over multiple graphics APIs (GA

Jun 17, 2022
Im3d is a small, self-contained library for immediate mode rendering of basic primitives

Im3d is a small, self-contained library for immediate mode rendering of basic primitives (points, lines, triangles), plus an immediate mode UI which provides 3d manipulation 'gizmos' and other tools. It is platform and graphics API agnostic and designed to be compatible with VR.

Jun 13, 2022
Horde3D is a small 3D rendering and animation engine. It is written in an effort to create an engine being as lightweight and conceptually clean as possible.

Horde3D Horde3D is a 3D rendering engine written in C++ with an effort being as lightweight and conceptually clean as possible. Horde3D requires a ful

Jun 22, 2022
A C++/DirectX 11 implementation of "A Scalable and Production Ready Sky and Atmosphere Rendering Technique"
A C++/DirectX 11 implementation of

Atmosphere Renderer A C++/DirectX 11 implementation of "A Scalable and Production Ready Sky and Atmosphere Rendering Technique" Features interactive e

Jun 5, 2022
This repository accompanies Ray Tracing Gems II: Next Generation Rendering with DXR, Vulkan, and OptiX
This repository accompanies Ray Tracing Gems II: Next Generation Rendering with DXR, Vulkan, and OptiX

Apress Source Code This repository accompanies Ray Tracing Gems II: Next Generation Rendering with DXR, Vulkan, and OptiX by Adam Marrs, Peter Shirley

Jun 21, 2022
Vire is a C++ voxel rendering engine. It is written in C++14 and uses OpenGL for graphics.

Vire Vire is a C++ voxel rendering engine. It is written in C++14 and uses OpenGL for graphics. Downloads If you'd just like to just download and try,

May 15, 2022