c2pa-c
This library implements C++ APIs that:
- Read and validate C2PA data from media files in supported formats.
- Add signed manifests to media files in supported formats.
WARNING: This is a prerelease version of this library. There may be bugs and unimplemented features, and the API is subject to change.
Installation
CMake setup
We build with CMake and you can use FetchContent like this:
c2pa_cpp
GIT_REPOSITORY https://github.com/contentauth/c2pa-c.git
GIT_TAG gpeacock/cmake_work`
)
FetchContent_MakeAvailable(c2pa_cpp)
And then add:
"${c2pa_cpp_SOURCE_DIR}/include"
to your include path.
Usage
To use this library, include the header file in your code as follows:
#include "c2pa.hpp"
Read and validate an istream
Use the Reader
constructor to read C2PA data from a stream. This constructor examines the specified stream for C2PA data in the given format and its return value is a Reader that can be used to extract more information. Exceptions are thrown on errors.
auto reader = c2pa::Reader(<"FORMAT">, <"STREAM">);
The parameters are:
<FORMAT>
- A MIME string format for the stream supported file formats.<STREAM>
- An open readable iostream. For example:
std::ifstream ifs("tests/fixtures/C.jpg", std::ios::binary);
// the Reader supports streams or file paths
auto reader = c2pa::Reader("image/jpeg", ifs);
// print out the Manifest Store information
printf("Manifest Store = %s", reader.json())
// write the thumbnail into a file
std::ofstream ofs("test_thumbail.jpg", std::ios::binary);
reader.get_resource("self#jumbf=c2pa.assertions/c2pa.thumbnail.claim.jpeg", ofs);
ifs.close();
Creating a manifest JSON definition
The manifest JSON string defines the C2PA manifest to add to the file.
A sample JSON manifest is provided in tests/fixtures/training.json.
For example:
const std::string manifest_json = R"{
"claim_generator": "c2pa_c_test/0.1",
"claim_generator_info": [
{
"name": "c2pa-c test",
"version": "0.1"
}
],
"assertions": [
{
"label": "c2pa.training-mining",
"data": {
"entries": {
"c2pa.ai_generative_training": { "use": "notAllowed" },
"c2pa.ai_inference": { "use": "notAllowed" },
"c2pa.ai_training": { "use": "notAllowed" },
"c2pa.data_mining": { "use": "notAllowed" }
}
}
}
]
};
Creating a Builder
Use the Builder
constructor to create a Builder
instance.
auto builder = Builder("<MANIFEST_JSON>");
The parameter is:
<MANIFEST_JSON>
- A string in JSON format as as described above, defining the manifest to be generated.
For example:
auto builder = Builder(manifest_json);
Creating Signer
A sample test signer is provided in the tests folder. It is important that the private key is is kept private. The test signer should only be used for testing and development. In production a the private key should be kept in KMS or another secure environment. The SDK requires the public cert chain to be passed in here.
Signer signer = Signer("<SIGNING_FUNCTION>","<SIGNING_ALG>", "<PUBLIC_CERTS>", "<TIMESTAMP_URL>");
The parameters are:
<SIGNING_FUNCTION>
- A signing function that returns a signature using<SIGNING_ALG>
over the bytes passed in.<SIGNING_ALG>
- TheC2paSigningAlg
fromc2pa.h
associated with the signing function.<PUBLIC_CERTS>
- A buffer containing the public cert chain.<TIMESTAMP_URL>
- An optional parameter containing a URL to a public Time Stamp Authority service.
For example:
Signer signer = Signer(test_signer, Es256, certs, "http://timestamp.digicert.com");
Signing and embedding a manifest
auto manifest_data = builder.sign(image_path, output_path, signer);
The parameters are:
<SOURCE_ASSET>
- A file path or an istream referencing the asset to sign.<OUTPUT_ASSET>
- A file path or an iostream referencing the asset to generate.<SIGNER>
- ASigner
instance.
For example:
auto manifest_data = builder.sign("source_asset.jpg", "output_asset.jpg", signer);
Development
This project has been tested on macOS and should also work on common Linux distributions.
Prerequisites
If you haven't already done so, install Rust.
Install cbindgen:
cargo install --force cbindgen
The unit tests require Ninja. Installation instructions are here:
https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages
Building
Building the library requires GNU make, which is installed on most macOS systems.
Enter this command to build the C library:
make release
The Makefile also has multiple targets:
unit-tests
to run C++ unit testsexamples
to build and run the C++ examples.all
to run everything.
Results are saved in the target
directory.
Testing
Build the unit tests by entering this make
command:
make test
Example
The simple C++ example in examples/training.cpp
uses the JSON for Modern C++ library class.
Build and run the example by entering this make
command:
make example
This example adds the manifest tests/fixtures/training.json
to the image file tests/fixtures/A.jpg
using the sample private key and certificate in the tests/fixtures
directory.
The example displays some text to standard out that summarizes whether AI training is allowed based on the specified manifest and then saves the resulting image file with attached manifest to target/example/training.jpg
.
Supported file formats
Extensions | MIME type |
---|---|
avi | video/msvideo , video/avi , application-msvideo |
avif | image/avif |
c2pa | application/x-c2pa-manifest-store |
dng | image/x-adobe-dng |
heic | image/heic |
heif | image/heif |
jpg , jpeg | image/jpeg |
m4a | audio/mp4 |
mp3 | "audio/mpeg" |
mp4 | video/mp4 , application/mp4 * |
mov | video/quicktime |
pdf | application/pdf ** |
png | image/png |
svg | image/svg+xml |
tif ,tiff | image/tiff |
wav | audio/x-wav |
webp | image/webp |
License
This package is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
Note that some components and dependent crates are licensed under different terms; please check the license terms for each crate and component for details.
Contributions and feedback
We welcome contributions to this project. For information on contributing, providing feedback, and about ongoing work, see Contributing.