Adds a utility to strip out FileAssetContents for given FileAsset types.

Adds a ```File::stripAssets``` utility method that is optionally compiled in. This allows removing in-band asset bytes from the file. It only does this for the provided asset types. Right now we only put image assets in-band, but in the future we may have fonts, scripts, sounds, other .riv files, etc so allowing the utility to only strip specific concrete file types is nice to have.

The next step will be to use this utility to show how you'd create an atlas out of the in-band images, strip out the images, and save a smaller .riv that uses images from that generated atlas.

I envision adding more utility methods like this for tools that want to manipulate Rive content at build/pre-package time. These should be able to be compiled out as they are rarely necessary at mass-consumption runtime (I doubt anyone wants these in WASM unless they're building their game engine, not just the player, in JS).

Diffs=
698af558e Fix linux build.
cb742eb08 Adds a utility to strip out FileAssetContents for given FileAsset types.
diff --git a/.rive_head b/.rive_head
index 9e28b1a..944c886 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-07186fc98800540f1723705547c9c8ef6f76044f
+698af558ea299e28e9524d4e874f33ba7b18aa99
diff --git a/build/macosx/build_rive.sh b/build/macosx/build_rive.sh
index 9e371f5..cf1149a 100755
--- a/build/macosx/build_rive.sh
+++ b/build/macosx/build_rive.sh
@@ -4,11 +4,14 @@
 source ../../dependencies/macosx/config_directories.sh
 
 CONFIG=debug
-
+TOOLS=
 for var in "$@"; do
     if [[ $var = "release" ]]; then
         CONFIG=release
     fi
+    if [[ $var = "tools" ]]; then
+        TOOLS="--with_rive_tools"
+    fi
 done
 
 if [[ ! -f "$DEPENDENCIES/bin/premake5" ]]; then
@@ -20,7 +23,7 @@
 export PREMAKE=$DEPENDENCIES/bin/premake5
 pushd ..
 
-$PREMAKE --file=./premake5.lua gmake2
+$PREMAKE --file=./premake5.lua gmake2 $TOOLS
 
 for var in "$@"; do
     if [[ $var = "clean" ]]; then
diff --git a/build/premake5.lua b/build/premake5.lua
index dcd92fd..65b58b1 100644
--- a/build/premake5.lua
+++ b/build/premake5.lua
@@ -103,6 +103,9 @@
         defines {"NDEBUG"}
         optimize "On"
 
+    filter {"options:with_rive_tools" }
+        defines {"WITH_RIVE_TOOLS"}
+
 newoption {
     trigger = "variant",
     value = "type",
@@ -126,3 +129,8 @@
     }
 
 }
+
+newoption {
+    trigger = "with_rive_tools",
+    description = "Enables tools usually not necessary for runtime."
+}
\ No newline at end of file
diff --git a/dev/test/premake5.lua b/dev/test/premake5.lua
index 1e3cb63..b1a9272 100644
--- a/dev/test/premake5.lua
+++ b/dev/test/premake5.lua
@@ -90,7 +90,7 @@
     "../../utils/**.cpp", -- no_op utils
 }
 
-defines {"TESTING", "ENABLE_QUERY_FLAT_VERTICES"}
+defines {"TESTING", "ENABLE_QUERY_FLAT_VERTICES", "WITH_RIVE_TOOLS"}
 
 filter "configurations:debug"
 defines {"DEBUG"}
diff --git a/include/rive/core/binary_reader.hpp b/include/rive/core/binary_reader.hpp
index 183e597..a1b9591 100644
--- a/include/rive/core/binary_reader.hpp
+++ b/include/rive/core/binary_reader.hpp
@@ -26,6 +26,7 @@
     bool reachedEnd() const;
 
     size_t lengthInBytes() const;
+    const uint8_t* position() const;
 
     std::string readString();
     Span<const uint8_t> readBytes();
diff --git a/include/rive/file.hpp b/include/rive/file.hpp
index d630536..c027fc3 100644
--- a/include/rive/file.hpp
+++ b/include/rive/file.hpp
@@ -6,6 +6,7 @@
 #include "rive/factory.hpp"
 #include "rive/file_asset_resolver.hpp"
 #include <vector>
+#include <set>
 
 ///
 /// Default namespace for Rive Cpp runtime code.
@@ -94,6 +95,17 @@
     /// index is out of range.
     Artboard* artboard(size_t index) const;
 
+#ifdef WITH_RIVE_TOOLS
+    /// Strips FileAssetContents for FileAssets of given typeKeys.
+    /// @param data the raw data of the file.
+    /// @param result is an optional status result.
+    /// @returns the data buffer of the file with the FileAssetContents objects
+    /// stripped out.
+    static const std::vector<uint8_t> stripAssets(Span<const uint8_t> data,
+                                                  std::set<uint16_t> typeKeys,
+                                                  ImportResult* result = nullptr);
+#endif
+
 private:
     ImportResult read(BinaryReader&, const RuntimeHeader&);
 };
diff --git a/src/core/binary_reader.cpp b/src/core/binary_reader.cpp
index d9e35db..18036b5 100644
--- a/src/core/binary_reader.cpp
+++ b/src/core/binary_reader.cpp
@@ -13,6 +13,7 @@
 }
 
 size_t BinaryReader::lengthInBytes() const { return m_Bytes.size(); }
+const uint8_t* BinaryReader::position() const { return m_Position; }
 
 bool BinaryReader::didOverflow() const { return m_Overflowed; }
 
diff --git a/src/file.cpp b/src/file.cpp
index eb4bef2..a010120 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -26,6 +26,8 @@
 #include "rive/animation/animation_state.hpp"
 #include "rive/animation/blend_state_1d.hpp"
 #include "rive/animation/blend_state_direct.hpp"
+#include "rive/assets/file_asset.hpp"
+#include "rive/assets/file_asset_contents.hpp"
 
 // Default namespace for Rive Cpp code
 using namespace rive;
@@ -287,3 +289,51 @@
     auto ab = this->artboard(name);
     return ab ? ab->instance() : nullptr;
 }
+
+#ifdef WITH_RIVE_TOOLS
+const std::vector<uint8_t> File::stripAssets(Span<const uint8_t> bytes,
+                                             std::set<uint16_t> typeKeys,
+                                             ImportResult* result) {
+    std::vector<uint8_t> strippedData;
+    strippedData.reserve(bytes.size());
+    BinaryReader reader(bytes);
+    RuntimeHeader header;
+    if (!RuntimeHeader::read(reader, header)) {
+        if (result) {
+            *result = ImportResult::malformed;
+        }
+
+    } else if (header.majorVersion() != majorVersion) {
+        if (result) {
+            *result = ImportResult::unsupportedVersion;
+        }
+    } else {
+        strippedData.insert(strippedData.end(), bytes.data(), reader.position());
+        const uint8_t* from = reader.position();
+        const uint8_t* to = reader.position();
+        uint16_t lastAssetType = 0;
+        while (!reader.reachedEnd()) {
+            auto object = readRuntimeObject(reader, header);
+            if (object == nullptr) {
+                continue;
+            }
+            if (object->is<FileAssetBase>()) {
+                lastAssetType = object->coreType();
+            }
+            if (object->is<FileAssetContents>() && typeKeys.find(lastAssetType) != typeKeys.end()) {
+                if (from != to) {
+                    strippedData.insert(strippedData.end(), from, to);
+                }
+                from = reader.position();
+            }
+            delete object;
+            to = reader.position();
+        }
+        if (from != to) {
+            strippedData.insert(strippedData.end(), from, to);
+        }
+        *result = ImportResult::success;
+    }
+    return strippedData;
+}
+#endif
\ No newline at end of file
diff --git a/tess/build/macosx/build_tess.sh b/tess/build/macosx/build_tess.sh
index 981d4ea..0054e3d 100755
--- a/tess/build/macosx/build_tess.sh
+++ b/tess/build/macosx/build_tess.sh
@@ -51,7 +51,7 @@
     fi
 done
 
-$PREMAKE --file=./premake5_tess.lua gmake2 --graphics=$GRAPHICS
+$PREMAKE --file=./premake5_tess.lua gmake2 --graphics=$GRAPHICS --with_rive_tools
 
 for var in "$@"; do
     if [[ $var = "clean" ]]; then
diff --git a/test/assets/jellyfish_test.riv b/test/assets/jellyfish_test.riv
new file mode 100644
index 0000000..37e6664
--- /dev/null
+++ b/test/assets/jellyfish_test.riv
Binary files differ
diff --git a/test/file_test.cpp b/test/file_test.cpp
index 54c0fe0..8cb589f 100644
--- a/test/file_test.cpp
+++ b/test/file_test.cpp
@@ -2,10 +2,12 @@
 #include <rive/node.hpp>
 #include <rive/shapes/rectangle.hpp>
 #include <rive/shapes/shape.hpp>
+#include <rive/assets/image_asset.hpp>
 #include "utils/no_op_renderer.hpp"
 #include "rive_file_reader.hpp"
 #include <catch.hpp>
 #include <cstdio>
+#include <cstring>
 
 TEST_CASE("file can be read", "[file]") {
     RenderObjectLeakChecker checker;
@@ -124,6 +126,46 @@
     REQUIRE(artboard->objects().size() == 7);
 }
 
+TEST_CASE("file with in-band images can have the stripped", "[file]") {
+    RenderObjectLeakChecker checker;
+    FILE* fp = fopen("../../test/assets/jellyfish_test.riv", "rb");
+    REQUIRE(fp != nullptr);
+
+    fseek(fp, 0, SEEK_END);
+    const size_t length = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    std::vector<uint8_t> bytes(length);
+    REQUIRE(fread(bytes.data(), 1, length, fp) == length);
+    fclose(fp);
+
+    rive::ImportResult result;
+    auto file = rive::File::import(bytes, &gNoOpFactory, &result);
+    REQUIRE(result == rive::ImportResult::success);
+    REQUIRE(file.get() != nullptr);
+    REQUIRE(file->artboard() != nullptr);
+
+    // Default artboard should be named Two.
+    REQUIRE(file->artboard()->name() == "Jellyfish");
+
+    // Strip nothing should result in the same file.
+    {
+        rive::ImportResult stripResult;
+        auto strippedBytes = rive::File::stripAssets(bytes, {}, &stripResult);
+        REQUIRE(stripResult == rive::ImportResult::success);
+        REQUIRE(bytes.size() == strippedBytes.size());
+        REQUIRE(std::memcmp(bytes.data(), strippedBytes.data(), bytes.size()) == 0);
+    }
+
+    // Strip image assets should result in a smaller file.
+    {
+        rive::ImportResult stripResult;
+        auto strippedBytes =
+            rive::File::stripAssets(bytes, {rive::ImageAsset::typeKey}, &stripResult);
+        REQUIRE(stripResult == rive::ImportResult::success);
+        REQUIRE(strippedBytes.size() < bytes.size());
+    }
+}
+
 // TODO:
 // ShapePaint (fill/stroke) needs to be implemented in WASM (jsFill/jsStroke) in
 // order to create Paint objects as necessary.
diff --git a/viewer/build/macosx/build_viewer.sh b/viewer/build/macosx/build_viewer.sh
index 31d7e07..6f1a360 100755
--- a/viewer/build/macosx/build_viewer.sh
+++ b/viewer/build/macosx/build_viewer.sh
@@ -46,10 +46,6 @@
     popd
 fi
 
-pushd ../../../build/macosx
-./build_rive.sh $CONFIG
-popd
-
 if [ $RENDERER = "skia" ]; then
     pushd ../../../skia/renderer/build/macosx
     ./build_skia_renderer.sh text $@