Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
Empty file added .gitmodules
Empty file.
100 changes: 100 additions & 0 deletions cpp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Build artifacts
build/
build_wasm/
build_http/
*.o
*.a
*.so
*.dylib
*.dll
*.exe
*.wasm
trustmark_example
trustmark_wasm_example

# CMake generated files
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
compile_commands.json
CTestTestfile.cmake
_deps/
*.cmake
!CMakeLists.txt
!cmake/

# Generated config files
TrustMarkCppConfig.cmake
TrustMarkCppConfigVersion.cmake

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
*.code-workspace

# Compiled libraries
libtrustmark_cpp.a
libtrustmark_cpp.so
libtrustmark_cpp.dylib

# Output directory (watermarked images)
output/*.jpg
output/*.png
output/*.jpeg
!output/.gitkeep

# ONNX models (fetched via script)
models/*.onnx
models/*.ort
models/*.config
!models/.gitkeep

# Dependencies (should be fetched via script)
onnxruntime/
third_party/ort/

# Cache directories
.cache/
__pycache__/
*.pyc

# System files
.DS_Store
Thumbs.db

# Debug files
*.dSYM/
*.pdb

# Temporary files
*.tmp
*.temp
*.log
*.bak
*.backup

# Coverage files
*.gcda
*.gcno
*.gcov
coverage/

# Profiling files
*.prof
*.out

# Package manager files
*.tar.gz
*.zip
*.7z

# WebAssembly build artifacts (if added later)
*.wasm
*.wasm.map
*.js.map
wasm_build/
107 changes: 107 additions & 0 deletions cpp/BUILD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Building TrustMark for wasmCloud

TrustMark ships as a WASIP2 HTTP component that runs under wasmCloud:

| Component | Input | Output | Routes |
|-----------|-------|--------|--------|
| `trustmark-http.wasm` | JPEG or PNG image | Watermarked PNG | `POST /encode[?bits=<100-bit-string>]` |

## Prerequisites

| Tool | Version | Notes |
|------|---------|-------|
| WASI SDK | 24+ | Set `WASI_SDK_PATH=/opt/wasi-sdk` |
| CMake | 3.15+ | |
| Python | 3.11+ | `pip3 install --break-system-packages flatbuffers` |
| wasm-tools | any | `cargo install wasm-tools` |
| wasi-preview1-component-adapter-provider | any | `cargo install wasi-preview1-component-adapter-provider` |
| wash (wasmCloud) | wasmCloud/wasmCloud main | `cargo build --bin wash` in the repo |

All commands below run from the `cpp/` directory unless noted.

## First-time setup

```bash
# From repo root — initialise submodule
git submodule update --init cpp/onnxruntime-wasi

# Stage TrustMark sources into the onnxruntime checkout
bash prepare_ort_build.sh

# Build ORT (once; ~20 min)
export WASI_SDK_PATH=/opt/wasi-sdk
cd onnxruntime-wasi && ./build_wasi.sh Release \
-Donnxruntime_USE_WEBGPU=ON \
-Donnxruntime_ENABLE_WEBASSEMBLY_SIMD=ON \
-Donnxruntime_EXTENDED_MINIMAL_BUILD=ON \
-Donnxruntime_WGSL_TEMPLATE=static && cd -
```

## Convert models

Models must be in `.with_runtime_opt.ort` format and placed in `models/`:

```bash
cd onnxruntime-wasi
python3 tools/python/convert_onnx_models_to_ort.py \
../models/encoder_P.onnx \
../models/decoder_P.onnx
cp *.with_runtime_opt.ort ../models/
cd -
```

## Build component

```bash
export WASI_SDK_PATH=/opt/wasi-sdk

# → build_http/trustmark-http.wasm
bash build_wasm_http.sh
```

## Run with wasmCloud

Each demo in `demo/` is a self-contained `wash dev` session.

```bash
# Build wash from wasmCloud/wasmCloud main
cd /path/to/wasmCloud && cargo build --bin wash
WASH=/path/to/wasmCloud/target/debug/wash

# CPU (port 8000) or GPU (port 8001)
cd demo/trustmark-cpu && $WASH dev
cd demo/trustmark-gpu && $WASH dev
```

**CPU vs GPU**: same `.wasm` binary, both modes. GPU is enabled by `USE_WEBGPU=1` in
`host_interfaces.config` of the GPU demo config; without it ORT uses CPU.

WebGPU requires a wasmCloud build that implements `wasi:webgpu` backed by the host
GPU (Metal/Vulkan/DX12). This support is in the `wasmCloud/wasmCloud` main branch.

Both demos mount `models/` at `/models` inside the component.

## Test

```bash
IMAGE=/path/to/trustmark/images/ufo_240.jpg

# Encode (CPU, port 8000)
curl -X POST http://localhost:8000/encode \
-H 'Content-Type: image/jpeg' --data-binary @"$IMAGE" -o watermarked.png

# Encode (GPU, port 8001)
curl -X POST http://localhost:8001/encode \
-H 'Content-Type: image/jpeg' --data-binary @"$IMAGE" -o watermarked_gpu.png

# Custom 100-bit watermark
AID=1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010
curl -X POST "http://localhost:8001/encode?bits=$AID" \
-H 'Content-Type: image/jpeg' --data-binary @"$IMAGE" -o watermarked_custom.png
```

## Models

Models are not in this repository. Place the following in `models/`:

- `encoder_P.with_runtime_opt.ort`
115 changes: 115 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
cmake_minimum_required(VERSION 3.16)
project(TrustMarkCpp VERSION 1.0.0 LANGUAGES CXX)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Find ONNX Runtime (avoid schema conflicts by not using find_package)
# Instead, manually specify the paths to avoid ONNX library conflicts

# Find OpenCV for image processing
find_package(OpenCV REQUIRED)

# Include directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/trustmark)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/ort/include)

# Create the library
add_library(trustmark_cpp
trustmark/trustmark.cpp
trustmark/onnx_session.cpp
trustmark/image_processor.cpp
trustmark/bch_ecc.cpp
)

# Detect ONNX Runtime library based on platform
if(APPLE)
set(ORT_LIB_EXT "dylib")
set(RPATH_LOADER_PATH "@loader_path")
elseif(UNIX)
set(ORT_LIB_EXT "so")
set(RPATH_LOADER_PATH "$ORIGIN")
elseif(WIN32)
set(ORT_LIB_EXT "dll")
set(RPATH_LOADER_PATH "$<TARGET_FILE_DIR:trustmark_cpp>")
endif()

# Find the ONNX Runtime library
set(ORT_LIB ${CMAKE_CURRENT_SOURCE_DIR}/third_party/ort/lib/libonnxruntime.${ORT_LIB_EXT})
if(NOT EXISTS ${ORT_LIB})
message(FATAL_ERROR "libonnxruntime.${ORT_LIB_EXT} not found at ${ORT_LIB}")
endif()

# Link libraries
target_link_libraries(trustmark_cpp
${ORT_LIB}
${OpenCV_LIBS}
)

# Set properties
set_target_properties(trustmark_cpp PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
PUBLIC_HEADER "trustmark/trustmark.h"
)

# Create example executables
add_executable(trustmark_example
examples/example.cpp
)
target_include_directories(trustmark_example PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(trustmark_example trustmark_cpp)

add_executable(encode_decode
examples/encode_decode.cpp
)
target_include_directories(encode_decode PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(encode_decode trustmark_cpp)

# Installation
install(TARGETS trustmark_cpp
EXPORT TrustMarkCppTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include
)

install(DIRECTORY trustmark/
DESTINATION include
FILES_MATCHING PATTERN "*.h"
)

# Export targets
install(EXPORT TrustMarkCppTargets
FILE TrustMarkCppTargets.cmake
NAMESPACE TrustMarkCpp::
DESTINATION lib/cmake/TrustMarkCpp
)

# Create config file
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/TrustMarkCppConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/TrustMarkCppConfig.cmake"
INSTALL_DESTINATION lib/cmake/TrustMarkCpp
)

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/TrustMarkCppConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)

install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/TrustMarkCppConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/TrustMarkCppConfigVersion.cmake"
DESTINATION lib/cmake/TrustMarkCpp
)
# Ensure rpath includes our third_party lib (cross-platform)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH "${RPATH_LOADER_PATH}/../third_party/ort/lib;${RPATH_LOADER_PATH}/../lib")
set(CMAKE_BUILD_RPATH "${CMAKE_CURRENT_SOURCE_DIR}/third_party/ort/lib")
Loading