Salta ai contenuti
getnextpdf.com

Pro edizionestabilità: Sperimentale

Anteprima C2PA — Riferimento approfondito

Questa pagina è il riferimento a livello di contratto per la superficie di anteprima C2PA (Content Credentials) in NextPDF Pro. Copre cinque simboli pubblici in NextPDF\Pro\Compliance\C2pa: la SPI C2paManifestEmbedder, il value object ManifestStore, il JumbfBoxParser, il descrittore C2paCapabilityStatus e l’Experimental\ExperimentalC2paEmbedder sottoposto a gate. Documenta inoltre il gate Feature::PREVIEW_C2PA_DRAFT e la sua variabile d’ambiente, NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT.

La superficie è sperimentale ed è suddivisa in due livelli. Il seam stabile — ManifestStore, C2paManifestEmbedder, JumbfBoxParser — è sempre raggiungibile e trasporta i byte del Manifest Store in entrambe le direzioni. La sintesi della bozza di manifest risiede unicamente in ExperimentalC2paEmbedder ed è disattivata per impostazione predefinita. Il profilo C2PA-PDF non è stato finalizzato dal gruppo di lavoro; il formato wire sintetizzato è ancorato a un commit di bozza. Non viene fatta alcuna dichiarazione di conformità, non esiste alcun percorso di verifica e l’abilitazione del flag di anteprima non può crearne alcuno. La vista orientata alle attività si trova nella pagina delle capacità.

Questa capacità è distribuita in NextPDF Pro (nextpdf/pro) e si attiva con un envelope di licenza di livello Pro. Un deployment privo di tale diritto non carica le classi della capacità. Confronta le edizioni e ottieni una licenza.

La licenza attiva la superficie di conformità Pro nel suo complesso. La superficie C2PA al suo interno rimane un’anteprima indipendentemente dal livello di licenza. La sintesi della bozza richiede inoltre il gate di processo qui documentato; una licenza Pro da sola non la abilita mai.

SimboloParametriComportamento predefinitoRestituisceGenera o fallisce conNote
C2paManifestEmbedderSPI di embed/extract solo-byte; nessun I/O; nessuna sintesi di claimInterfaccia seam congelata e neutrale rispetto al vendor.
C2paManifestEmbedder::embed()string $pdfBytes, ManifestStore $storeIncorpora $store->toBytes() nella posizione dichiarata dal profilo; uno Store vuoto PUÒ fare round-trip come no-opstring nuovi byte PDFC2paException in caso di qualsiasi errore di embed (Store sovradimensionato, PDF non valido, collisione con la posizione del profilo)Le implementazioni non modificano né trattengono mai i byte in input.
C2paManifestEmbedder::extract()string $pdfBytesSonda di rilevamento economica; il caso senza Store alloca quasi nulla?ManifestStore (null in assenza)Sottoclasse di C2paException quando è presente uno Store che viola un invariante di rafforzamentoUno Store non nullo ha già superato il rafforzamento di JumbfBoxParser.
ManifestStore::fromBoxes()array $boxes (list<JumbfBox>)Incapsula una lista ordinata di box validata dal parserselfNon genera eccezioni di per sé; la costruzione manuale di JumbfBox applica lo stesso rafforzamentoIl costruttore è privato; l’ordine dei box è determinante per l’uguaglianza in round-trip.
ManifestStore::empty()nessunoStore con zero box radiceselfNon genera eccezionitoBytes() di uno Store vuoto è la stringa vuota.
ManifestStore::isEmpty()nessunoVerifica la presenza di zero box radiceboolNon genera eccezioni
ManifestStore::toBytes()nessunoConcatena le serializzazioni dei box radicestringNon genera eccezioniQuesta sequenza di byte è ciò che un embedder scrive.
ManifestStore::size()nessunoLunghezza in byte di toBytes()int (>= 0)Non genera eccezioni
JumbfBoxParser::__construct()tre override facoltativi dei limitiLimiti di produzione: 64 MiB per box, 128 MiB totali, 4096 figli per superboxJumbfBoxParserNon genera eccezioniIl limite di profondità è fissato a MAX_DEPTH (8) e non è regolabile dal costruttore.
JumbfBoxParser::parse()string $bytesValida e materializza i box radice; l’input vuoto produce []list<JumbfBox>JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException, MalformedJumbfExceptionStateless; non restituisce mai un grafo parziale; le chiamate concorrenti su una stessa istanza sono sicure.
C2paCapabilityStatus::__construct()sei campi readonly con nomeCostruisce un’istanza di descrittore arbitrariaC2paCapabilityStatusNon genera eccezionicurrent() è il costruttore canonico.
C2paCapabilityStatus::current()nessunoLegge il gate in tempo reale; cabla i booleani di dichiarazioneC2paCapabilityStatusNon genera eccezionigenerallyAvailable e conformanceClaimed sono sempre false.
C2paCapabilityStatus::summary()nessunoTesto di stato su una rigastringNon genera eccezioniFormulato per non veicolare alcuna dichiarazione di GA o conformità.
Featureenum backed da stringa, 1 casoCaso unico PREVIEW_C2PA_DRAFT; costante ENV_PREVIEW_C2PA_DRAFTcaso enumNulla all’accesso del casoGate di stabilità circoscritto; distinto dal diritto di licenza.
Feature::isEnabled()nessunoLegge getenv() in tempo reale; confronto stretto con la stringa 1boolNon genera eccezioniVariabile assente o qualsiasi altro valore, incluso 0, true, yes, è disattivato.
ExperimentalC2paEmbedder::__construct()nessunoControllo del gate fail-closed al momento della costruzioneExperimentalC2paEmbedderLogicException quando Feature::PREVIEW_C2PA_DRAFT è disattivatoNon esiste alcun fallback silenzioso.
ExperimentalC2paEmbedder::buildManifestStore()string $sourceBytes, string $producer (non vuoto)Costruisce uno Store in forma di bozza che vincola $sourceBytes tramite SHA-256ManifestStore\JsonException in caso di errore di encoding del payload; sottoclassi di C2paException dalla costruzione dei boxOmette il box Claim Signature c2cs; l’output è non firmato per costruzione.
interface C2paManifestEmbedder
public function embed(string $pdfBytes, ManifestStore $store): string;
public function extract(string $pdfBytes): ?ManifestStore;
final readonly class ManifestStore
public static function fromBoxes(array $boxes): self
public static function empty(): self
public function isEmpty(): bool
public function toBytes(): string
public function size(): int
final class JumbfBoxParser
public const int MAX_DEPTH = 8;
public const int MAX_PER_BOX_BYTES = 64 * 1024 * 1024;
public const int MAX_TOTAL_BYTES = 128 * 1024 * 1024;
public const int MAX_CHILDREN_PER_SUPERBOX = 4096;
public const array SUPERBOX_TBOXES = ['jumb', 'c2pa', 'c2ma', 'c2as', 'c2cl', 'c2cs', 'c2vc'];
public function __construct(
private readonly int $maxPerBoxBytes = self::MAX_PER_BOX_BYTES,
private readonly int $maxTotalBytes = self::MAX_TOTAL_BYTES,
private readonly int $maxChildrenPerSuperbox = self::MAX_CHILDREN_PER_SUPERBOX,
)
public function parse(string $bytes): array
final readonly class C2paCapabilityStatus
public const string MATURITY_PREVIEW_DRAFT = 'preview-draft';
public function __construct(
public bool $previewEnabled,
public bool $generallyAvailable,
public bool $conformanceClaimed,
public string $maturity,
public string $specPin,
public string $envGate,
)
public static function current(): self
public function summary(): string
enum Feature: string
case PREVIEW_C2PA_DRAFT = 'preview_c2pa_draft';
public const string ENV_PREVIEW_C2PA_DRAFT = 'NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT';
public function isEnabled(): bool
final class ExperimentalC2paEmbedder
public const string SPEC_PIN_SHA = '4e2afed8f3ace20d41317e2e386c9340d2959d55';
public const string SPEC_PIN_DATE = '2026-04-26';
public function __construct()
public function buildManifestStore(string $sourceBytes, string $producer): ManifestStore
  • Suddivisione in due livelli. Il seam stabile (ManifestStore, C2paManifestEmbedder, JumbfBoxParser) è sempre raggiungibile. La sintesi della bozza esiste unicamente in NextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedder dietro il gate disattivato per impostazione predefinita. L’estrazione e il trasporto dei byte non richiedono mai il gate; la sintesi lo richiede sempre.
  • Invarianti del seam. Il contratto C2paManifestEmbedder è solo-byte: nessun oggetto PDF in memoria attraversa il seam, le implementazioni non eseguono alcun I/O di rete o filesystem e il seam non assembla mai da sé le asserzioni di claim. extract() restituisce null per segnalare l’assenza; non genera mai eccezioni per l’assenza.
  • Semantica dello Store. ManifestStore è una lista ordinata immutabile di istanze JumbfBox radice, secondo il modello Manifest Store di C2PA 2.1 §11.1.1: un contenitore JUMBF che aggrega uno o più manifest, indirizzabili tramite URI. Non espone alcun accessor a livello di claim. L’ordine dei box è preservato ed è determinante per l’uguaglianza in round-trip.
  • Limiti di rafforzamento. JumbfBoxParser rifiuta incondizionatamente gli input che superano qualsiasi limite: dimensione per box oltre 64 MiB, store cumulativo oltre 128 MiB, annidamento più profondo di 8 livelli o più di 4096 figli in un singolo superbox. Nessun flag di policy disabilita questi limiti. Limiti più stringenti sono iniettabili dal costruttore per processi con memoria limitata.
  • Rifiuto strutturale. Il parser rifiuta inoltre, in modalità fail-closed: LBox = 0 (BMFF fino a EOF), LBox = 1 (XLBox lunghezza a 64 bit), un LBox inferiore all’header di 8 byte, il troncamento oltre l’input residuo, byte TBox al di fuori dell’ASCII stampabile (0x20–0x7E), il rientro tramite offset (cicli) e la tassellatura non esatta dei figli di un payload di superbox. Non restituisce mai un grafo costruito parzialmente.
  • Instradamento dei superbox. I valori TBox in SUPERBOX_TBOXES vengono analizzati ricorsivamente come sequenze di figli; ogni altro TBox è una foglia con un payload opaco. cbor è deliberatamente trattato come una foglia per la sicurezza del parser; i livelli a monte rianalizzano il suo payload quando necessario.
  • Gate di processo. Feature::PREVIEW_C2PA_DRAFT è disattivato per impostazione predefinita. isEnabled() restituisce true solo quando NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT è esattamente uguale alla stringa 1. La lettura è in tempo reale a ogni chiamata; nulla viene memoizzato.
  • Costruzione fail-closed. new ExperimentalC2paEmbedder() genera LogicException mentre il gate è disattivato. Il messaggio nomina il flag, la variabile d’ambiente e lo SHA e la data della bozza ancorata. Un chiamante non può raggiungere accidentalmente la sintesi della bozza.
  • Forma della sintesi. buildManifestStore() emette un superbox c2pa contenente un manifest c2ma, che contiene un assertion store c2as (una asserzione c2pa.hash.data) e un claim c2cl. L’asserzione registra una asserzione di hash SHA-256 su $sourceBytes; poiché il box Claim Signature c2cs è omesso e l’output è non firmato, questo NON è un hard binding C2PA né un verdetto di provenienza — segue soltanto la forma strutturale descritta nel §9.1. I payload dei Description box trasportano un UUID di tipo, i toggle 0x03 e un’etichetta UTF-8 terminata da null, secondo C2PA 2.1 §11.1.4.1.1–11.1.4.1.2.
  • Nessuna Claim Signature. Il box c2cs — secondo C2PA 2.1 §11.1.4.4 un singolo box di contenuto CBOR etichettato c2pa.signature — è intenzionalmente omesso dallo Store sintetizzato. L’output è non firmato per costruzione. Questa è la regione del profilo ritenuta più probabile a mutare prima del freeze del gruppo di lavoro.
  • Ancoraggio alla bozza, nessuna garanzia di BC. Il formato wire sintetizzato è ancorato a SPEC_PIN_SHA (4e2afed8…, datato 2026-04-26) di c2pa-org/specifications. Può cambiare senza preavviso e non comporta alcuna garanzia di retrocompatibilità.
  • Invariante di onestà. C2paCapabilityStatus::current() cabla generallyAvailable e conformanceClaimed a false. Nessuna configurazione o flag d’ambiente inverte alcuno dei due booleani. Solo previewEnabled riflette il gate; maturity è il token non dichiarante preview-draft.
  • Impostare la variabile del gate a 0, true, yes, on o a una stringa vuota lascia il gate disattivato. Solo la stringa esatta 1 lo abilita.
  • Le modifiche di putenv() hanno effetto alla successiva chiamata di isEnabled() perché la lettura è in tempo reale. Un gate commutato a metà processo viene osservato immediatamente.
  • extract() distingue due esiti: null quando non è presente alcuno Store (economico, senza eccezioni) e una sottoclasse di C2paException generata quando è presente uno Store ostile o malformato. L’assenza non è mai un errore; la presenza più la malformazione lo è sempre.
  • JumbfBoxParser::parse('') restituisce la lista vuota. Un ManifestStore vuoto ma presente fa round-trip su se stesso; il seam non lo collassa a null.
  • Incorporare uno Store vuoto PUÒ restituire l’input invariato. Il contratto del seam consente questo no-op ma non lo impone.
  • I grafi JumbfBox costruiti manualmente eseguono lo stesso rafforzamento al momento della costruzione: i controlli di lunghezza e ASCII del TBox, il limite di profondità, l’invariante di profondità dei figli, la regola di esclusività payload-o-figli e il limite di dimensione per box. Una bomb costruita manualmente fallisce alla costruzione, non al momento dell’embed.
  • Ogni eccezione del parser trasporta campi strutturati — capKind/observed/cap, offset o kind — così che la telemetria non debba scandagliare le stringhe dei messaggi. Tutte le sottoclassi estendono C2paException (essa stessa una RuntimeException), che è il tipo di catch generale.
  • Il docblock del parser vieta di ingoiare silenziosamente queste eccezioni; i consumatori le espongono o le rimappano in modo intenzionale.
  • buildManifestStore() codifica i payload JSON con JSON_THROW_ON_ERROR; una stringa $producer che non è UTF-8 valido fallisce con \JsonException prima che venga costruito qualsiasi box.
  • Un risultato di extract() ben formato è una mera affermazione strutturale. Non c’è alcuna validazione dei claim, alcuna verifica di firma né alcuna valutazione di fiducia su nessun punto di questa superficie. Il riconoscimento non è un verdetto di provenienza.
  • Nessuna chiave di firma, certificato o struttura COSE viene elaborata da questa superficie. L’unica operazione crittografica è un hash di contenuto SHA-256 all’interno del percorso di sintesi sottoposto a gate.
DichiarazioneStandardClausola
I manifest si serializzano in un unico store JUMBF che contiene più manifest, indirizzabili tramite URI.C2PA 2.1§11.1.1 (p63.b)
Le etichette dei Description box sono UTF-8 terminate da null con intervalli esclusi; i toggle sono definiti per tutti i Description box.C2PA 2.1§11.1.4.1.1–11.1.4.1.2 (p63.a)
Il box Claim Signature è etichettato c2pa.signature, tipizzato c2cs e contiene un singolo box di contenuto CBOR.C2PA 2.1§11.1.4.4 (p63.c)
Un hard binding lega crittograficamente un manifest al suo asset ed espone le modifiche — l’asserzione di hash non firmata dell’anteprima NON soddisfa questo requisito.C2PA 2.1§9.1 (p57)

Tutte le clausole sono parafrasate. NextPDF non riproduce testo normativo. NextPDF non detiene alcuna certificazione e non ne concede alcuna. Le affermazioni di cui sopra sono affermazioni di allineamento strutturale riguardo alla disposizione dei box, alle etichette e ai binding — non sono risultati di test di conformità, non sono attestazioni di terze parti e non sono una dichiarazione di conformità C2PA o ISO. Il profilo C2PA-PDF non è finalizzato; il formato wire sintetizzato traccia un commit di bozza ancorato. C2paCapabilityStatus codifica questa postura nel codice: generallyAvailable e conformanceClaimed sono false in ogni configurazione. L’output di questa superficie non è una Content Credential verificabile e in NextPDF non esiste alcun percorso di verifica.

  • La grammatica dei box JUMBF che il parser implementa (LBox big-endian a 4 byte, TBox ASCII a 4 byte, payload; i superbox annidano box figli) segue ISO 19566-5; tale standard è al di fuori del corpus citato, pertanto il comportamento del parser è fondato sul sorgente del prodotto, non su una citazione di specifica.

  • Mantieni il gate disattivato in produzione. La sintesi della bozza non aggiunge alcuna capacità durevole; i byte emessi sono transitori e dovrebbero essere reincorporati una volta che sarà disponibile un adapter stabile.

  • Verifica ExperimentalC2paEmbedder::SPEC_PIN_SHA rispetto al commit di bozza che la tua pipeline si aspetta. Esegui composer c2pa:draft-status in CI (uscita 0 aggiornato, 1 avviso soft, 2 fallimento hard) per rilevare l’obsolescenza dell’ancoraggio.

  • Tratta C2paCapabilityStatus::current() come l’unica fonte di verità quando esponi lo stato C2PA in strumenti o UI. Non ridichiarare i suoi booleani manualmente; summary() è sicuro per log ed endpoint di stato.

  • Cattura C2paException come tipo generale quando consumi extract() o parse(). Mappa le quattro sottoclassi a contatori di telemetria distinti usando i loro campi strutturati.

  • Inietta limiti più stringenti tramite il costruttore di JumbfBoxParser per processi di verifica con memoria limitata; i valori predefiniti sono limiti di produzione generosi.

  • C2paCapabilityStatus::__construct() è pubblico, quindi un’istanza costruita manualmente può trasportare booleani arbitrari. Tale istanza è solo un value object; non altera alcun comportamento.

Questa pagina documenta esclusivamente il comportamento osservabile esternamente e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi dei file di runbook e i prefissi dei ticket sono fuori ambito.