Reading manifest data
- JavaScript
- Python
- Node.js
- C++
- Rust
Once you've used createC2pa to create an instance of c2pa-web (for example in c2pa in this example), use c2pa.reader.fromBlob() to create a Reader for an asset.
Then use Reader's manifestStore() method to read manifest data (if any) from the asset.
For example:
import { createC2pa } from '@contentauth/c2pa-web';
import wasmSrc from '@contentauth/c2pa-web/resources/c2pa.wasm?url';
const c2pa = createC2pa({ wasmSrc });
const response = await fetch(
'https://contentauth.github.io/example-assets/images/Firefly_tabby_cat.jpg'
);
const blob = await response.blob();
const reader = await c2pa.reader.fromBlob(blob.type, blob);
const manifestStore = await reader.manifestStore();
console.log(manifestStore);
// Free SDK objects when they are no longer needed to avoid memory leaks.
await reader.free();
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 c2pa
import urllib.request
TRUST_ANCHORS_URL = "https://contentcredentials.org/trust/anchors.pem"
def load_trust_anchors():
try:
with urllib.request.urlopen(TRUST_ANCHORS_URL) as response:
anchors = response.read().decode('utf-8')
settings = {
"verify": {
"verify_cert_anchors": True
},
"trust": {
"trust_anchors": anchors
}
}
c2pa.load_settings(settings)
except Exception as e:
print(f"Warning: Could not load trust anchors from {TRUST_ANCHORS_URL}: {e}")
def read_c2pa_data(media_path: str):
print(f"Reading {media_path}")
try:
with c2pa.Reader(media_path) as reader:
print(reader.detailed_json())
except Exception as e:
print(f"Error reading C2PA data from {media_path}: {e}")
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) < 2:
media_path = "tests/fixtures/cloud.jpg"
else:
media_path = sys.argv[1]
load_trust_anchors()
read_c2pa_data(media_path)
Use the c2pa.read() function to read a manifest; for example:
// read-manifest.ts
import { Reader } from '@contentauth/c2pa-node';
async function main(): Promise<void> {
const inputPath = process.argv[2];
if (!inputPath) {
console.error('Usage: ts-node read-manifest.ts <path-to-asset>');
process.exit(1);
}
const reader = await Reader.fromAsset({ path: inputPath });
if (!reader) {
console.log('No C2PA manifest found.');
return;
}
const manifestStore = reader.json();
console.log(JSON.stringify(manifestStore, null, 2));
// If you only want the active manifest:
const active = reader.getActive();
if (active) {
console.log('Active manifest label:', manifestStore.active_manifest);
}
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Using a buffer
import fs from 'node:fs/promises';
import { Reader } from '@contentauth/c2pa-node';
async function readFromBuffer(filePath: string): Promise<void> {
const buffer = await fs.readFile(filePath);
const reader = await Reader.fromAsset({ buffer, mimeType: 'jpeg' }); // adjust mimeType as needed
if (!reader) {
console.log('No C2PA manifest found.');
return;
}
console.log(JSON.stringify(reader.json(), null, 2));
}
Use the read_file function to read C2PA data from the specified file. This function examines the specified asset file for C2PA data and returns a JSON report if it finds any; it throws exceptions on errors. If there are validation errors, the report includes a validation_status field.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include "c2pa.hpp"
#include "test_signer.hpp"
using namespace std;
namespace fs = std::filesystem;
using namespace c2pa;
auto json_store = C2pa::read_file("work/media_file.jpg", "output/data_dir")
Where:
work/media_file.jpgis the asset file to read.output/data_diris the optional path to data output directory; If provided, the function extracts any binary resources, such as thumbnails, icons, and C2PA data into that directory. These files are referenced by the identifier fields in the manifest store report.
Use the Reader struct to read manifest data from a file or stream.
Reading from a file
Use from_file to read manifest data from a file:
use std::{
io::{Cursor, Write},
process::{Command, Stdio},
};
use anyhow::Result;
use c2pa::{settings::load_settings_from_str, Builder, CallbackSigner, Reader};
use c2pa_crypto::raw_signature::SigningAlg;
use serde_json::json;
const TEST_IMAGE: &[u8] = include_bytes!("../tests/fixtures/CA.jpg");
const CERTS: &[u8] = include_bytes!("../tests/fixtures/certs/ed25519.pub");
const PRIVATE_KEY: &[u8] = include_bytes!("../tests/fixtures/certs/ed25519.pem");
use c2pa::Reader;
let reader = Reader::from_file("path/to/file.jpg").unwrap();
There is also an asynchronous version of this method, from_stream_async.
Reading from a stream
Use from_stream to read manifest data from a stream:
use std::{
io::{Cursor, Write},
process::{Command, Stdio},
};
use anyhow::Result;
use c2pa::{settings::load_settings_from_str, Builder, CallbackSigner, Reader};
use c2pa_crypto::raw_signature::SigningAlg;
use serde_json::json;
const TEST_IMAGE: &[u8] = include_bytes!("../tests/fixtures/CA.jpg");
const CERTS: &[u8] = include_bytes!("../tests/fixtures/certs/ed25519.pub");
const PRIVATE_KEY: &[u8] = include_bytes!("../tests/fixtures/certs/ed25519.pem");
let mut stream = Cursor::new(include_bytes!("../tests/fixtures/CA.jpg"));
let reader = Reader::from_stream("image/jpeg", stream).unwrap();
println!("{}", reader.json());
There is also an asynchronous version of this method, from_stream_async.