Reading and verifying manifest data
- Rust
- C++
- Python
- JavaScript
Use the Reader struct to read manifest data from a file or stream.
Open a file and use from_context with with_stream to read manifest data:
use c2pa::{Context, Reader, Result};
use std::fs::File;
fn main() -> Result<()> {
let context = Context::new();
let stream = File::open("path/to/file.jpg")?;
let reader = Reader::from_context(context)
.with_stream("image/jpeg", stream)?;
println!("{}", reader.json());
Ok(())
}
The with_stream() format parameter accepts either a MIME type or a file extension as an argument.
Use the Reader constructor to read C2PA data from a file or stream. Pass a shared pointer to a Context as the first argument to configure SDK behavior; for the default configuration, use std::make_shared<c2pa::Context>().
Reading from a file
#include "c2pa.hpp"
#include <iostream>
#include <memory>
auto context = std::make_shared<c2pa::Context>();
auto reader = c2pa::Reader(context, "work/media_file.jpg");
std::cout << reader.json() << std::endl;
Reading from a stream
#include "c2pa.hpp"
#include <fstream>
#include <iostream>
#include <memory>
auto context = std::make_shared<c2pa::Context>();
std::ifstream ifs("work/media_file.jpg", std::ios::binary);
auto reader = c2pa::Reader(context, "image/jpeg", ifs);
std::cout << reader.json() << std::endl;
If there are validation errors, the report includes a validation_status field.
Use the c2pa.Reader object to read manifest data from a file or stream and perform validation on the manifest store.
This example shows how to read a C2PA manifest embedded in a media file, and validate that it is trusted according to the official trust anchor certificate list. The output is printed as prettified JSON.
import sys
import json
import urllib.request
from c2pa import Context, Reader
TRUST_ANCHORS_URL = "https://contentcredentials.org/trust/anchors.pem"
def load_trust_anchors():
try:
with urllib.request.urlopen(TRUST_ANCHORS_URL) as response:
return response.read().decode('utf-8')
except Exception as e:
print(f"Warning: Could not load trust anchors from {TRUST_ANCHORS_URL}: {e}")
return None
def read_c2pa_data(media_path: str):
print(f"Reading {media_path}")
try:
anchors = load_trust_anchors()
config = {"verify": {"verify_cert_anchors": True}}
if anchors:
config["trust"] = {"trust_anchors": anchors}
ctx = Context.from_dict(config)
with Reader(media_path, context=ctx) as reader:
print(reader.json())
except Exception as e:
print(f"Error reading C2PA data from {media_path}: {e}")
sys.exit(1)
if __name__ == '__main__':
media_path = sys.argv[1] if len(sys.argv) >= 2 else "tests/fixtures/cloud.jpg"
read_c2pa_data(media_path)
Initialize the SDK with createC2pa, then use reader.fromBlob to open an asset. Call manifestStore for the full store, or activeManifest for the active claim.
Always call reader.free() when finished, and c2pa.dispose() when tearing down the worker.
Read from a Blob
With Vite (or similar), load the Wasm URL:
import { createC2pa } from '@contentauth/c2pa-web';
import wasmSrc from '@contentauth/c2pa-web/resources/c2pa.wasm?url';
const c2pa = await createC2pa({ wasmSrc });
const response = await fetch('/signed-image.jpg');
const blob = await response.blob();
const reader = await c2pa.reader.fromBlob(blob.type, blob);
if (!reader) {
console.log('No C2PA manifest found.');
c2pa.dispose();
return;
}
const manifestStore = await reader.manifestStore();
console.log(JSON.stringify(manifestStore, null, 2));
const active = await reader.activeManifest();
console.log('Active title:', active.title);
await reader.free();
c2pa.dispose();
Optional per-read settings override the defaults passed to createC2pa:
const reader = await c2pa.reader.fromBlob(blob.type, blob, {
verify: { verifyAfterReading: false, verifyTrust: true },
});
Inline Wasm (no separate .wasm request)
For constrained environments, use @contentauth/c2pa-web/inline (larger bundle):
import { createC2pa } from '@contentauth/c2pa-web/inline';
const c2pa = await createC2pa();
See the c2pa-web README for CDN-hosted Wasm and API details.