Zum Inhalt springen
getnextpdf.com

Pro EditionStabilität: Experimentell

C2PA-Vorschau — Detailreferenz

Diese Seite ist die Referenz auf Vertragsebene für die C2PA-Vorschau-Oberfläche (Content Credentials) in NextPDF Pro. Sie behandelt fünf öffentliche Symbole in NextPDF\Pro\Compliance\C2pa: die C2paManifestEmbedder-SPI, das ManifestStore-Wertobjekt, den JumbfBoxParser, den C2paCapabilityStatus-Deskriptor und den gegateten Experimental\ExperimentalC2paEmbedder. Sie dokumentiert außerdem das Feature::PREVIEW_C2PA_DRAFT-Gate und seine Umgebungsvariable, NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT.

Die Oberfläche ist experimentell und in zwei Schichten aufgeteilt. Die stabile Naht — ManifestStore, C2paManifestEmbedder, JumbfBoxParser — ist stets erreichbar und trägt Manifest-Store-Bytes in beide Richtungen. Die Synthese von Entwurfsmanifesten existiert ausschließlich im ExperimentalC2paEmbedder und ist standardmäßig deaktiviert. Das C2PA-PDF-Profil ist von der Arbeitsgruppe nicht finalisiert; das synthetisierte Wire-Format ist auf einen Entwurfs-Commit fixiert. Es wird kein Konformitätsanspruch erhoben, es gibt keinen Verifizierungspfad, und das Aktivieren des Vorschau-Flags kann keines von beidem erzeugen. Die aufgabenorientierte Sicht befindet sich auf der Fähigkeitsseite.

Diese Fähigkeit wird in NextPDF Pro (nextpdf/pro) ausgeliefert und wird mit einem Lizenzumschlag der Pro-Stufe aktiviert. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Fähigkeit nicht. Editionen vergleichen und eine Lizenz erwerben.

Die Lizenz aktiviert die Pro-Compliance-Oberfläche als Ganzes. Die darin enthaltene C2PA-Oberfläche bleibt unabhängig von der Lizenzstufe eine Vorschau. Die Entwurfssynthese erfordert zusätzlich das hier dokumentierte Prozess-Gate; eine Pro-Lizenz allein aktiviert sie niemals.

SymbolParameterStandardverhaltenRückgabeWirft oder scheitert mitAnmerkungen
C2paManifestEmbedderRein bytebasierte Embed-/Extract-SPI; keine I/O; keine Claim-SyntheseEingefrorene, herstellerneutrale Nahtschnittstelle.
C2paManifestEmbedder::embed()string $pdfBytes, ManifestStore $storeBettet $store->toBytes() an dem vom Profil deklarierten Ort ein; ein leerer Store DARF als No-Op round-trippenstring neue PDF-BytesC2paException bei jedem Embed-Fehler (übergroßer Store, ungültiges PDF, Profilort-Kollision)Implementierungen mutieren oder behalten die Eingabe-Bytes niemals.
C2paManifestEmbedder::extract()string $pdfBytesGünstige Erkennungssonde; der Fall ohne Store allokiert nahezu nichts?ManifestStore (null bei Fehltreffer)C2paException-Unterklasse, wenn ein Store vorhanden ist, aber eine Härtungsinvariante verletztEin Store ungleich null hat die JumbfBoxParser-Härtung bereits bestanden.
ManifestStore::fromBoxes()array $boxes (list<JumbfBox>)Umschließt eine parser-validierte, geordnete Box-ListeselfWirft selbst nicht; die handgebaute JumbfBox-Konstruktion erzwingt dieselbe HärtungDer Konstruktor ist privat; die Box-Reihenfolge ist für die Round-Trip-Gleichheit tragend.
ManifestStore::empty()keineStore mit null Root-BoxenselfWirft nichttoBytes() eines leeren Store ist die leere Zeichenkette.
ManifestStore::isEmpty()keinePrüft auf null Root-BoxenboolWirft nicht
ManifestStore::toBytes()keineVerkettet die Root-Box-SerialisierungenstringWirft nichtDiese Byte-Sequenz ist das, was ein Embedder schreibt.
ManifestStore::size()keineByte-Länge von toBytes()int (>= 0)Wirft nicht
JumbfBoxParser::__construct()drei optionale Cap-OverridesProduktions-Caps: 64 MiB pro Box, 128 MiB gesamt, 4096 Kinder pro SuperboxJumbfBoxParserWirft nichtDer Tiefen-Cap ist fest auf MAX_DEPTH (8) gesetzt und nicht per Konstruktor einstellbar.
JumbfBoxParser::parse()string $bytesValidiert und materialisiert die Root-Boxen; leere Eingabe ergibt []list<JumbfBox>JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException, MalformedJumbfExceptionZustandslos; gibt niemals einen Teilgraphen zurück; nebenläufige Aufrufe auf einer Instanz sind sicher.
C2paCapabilityStatus::__construct()sechs benannte readonly-FelderErzeugt eine beliebige Deskriptor-InstanzC2paCapabilityStatusWirft nichtcurrent() ist der kanonische Konstruktor.
C2paCapabilityStatus::current()keineLiest das Gate live; verdrahtet die Claim-Booleans festC2paCapabilityStatusWirft nichtgenerallyAvailable und conformanceClaimed sind stets false.
C2paCapabilityStatus::summary()keineEinzeiliger StatustextstringWirft nichtSo formuliert, dass er keinen GA- oder Konformitätsanspruch trägt.
Featurestring-basiertes Enum, 1 FallEinzelner Fall PREVIEW_C2PA_DRAFT; Konstante ENV_PREVIEW_C2PA_DRAFTEnum-FallNichts beim Fall-ZugriffGezieltes Stabilitäts-Gate; getrennt von der Lizenzberechtigung.
Feature::isEnabled()keineLiest getenv() live; strikter Vergleich gegen die Zeichenkette 1boolWirft nichtFehlende Variable oder jeder andere Wert, einschließlich 0, true, yes, ist aus.
ExperimentalC2paEmbedder::__construct()keineFail-closed-Gate-Prüfung zur KonstruktionszeitExperimentalC2paEmbedderLogicException, wenn Feature::PREVIEW_C2PA_DRAFT aus istEs existiert kein stiller Fallback.
ExperimentalC2paEmbedder::buildManifestStore()string $sourceBytes, string $producer (nicht leer)Baut einen entwurfsförmigen Store, der $sourceBytes per SHA-256 bindetManifestStore\JsonException bei Payload-Enkodierungsfehler; C2paException-Unterklassen aus der Box-KonstruktionLässt die c2cs Claim Signature Box weg; die Ausgabe ist konstruktionsbedingt unsigniert.
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
  • Zweischichtige Aufteilung. Die stabile Naht (ManifestStore, C2paManifestEmbedder, JumbfBoxParser) ist stets erreichbar. Die Entwurfssynthese existiert ausschließlich in NextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedder hinter dem standardmäßig deaktivierten Gate. Extraktion und Byte-Transport erfordern das Gate nie; die Synthese erfordert es stets.
  • Nahtinvarianten. Der C2paManifestEmbedder-Vertrag ist rein bytebasiert: Keine In-Memory-PDF-Objekte überqueren die Naht, Implementierungen führen keine Netzwerk- oder Dateisystem-I/O aus, und die Naht setzt niemals selbst Claim-Assertionen zusammen. extract() gibt null zurück, um Abwesenheit zu signalisieren; bei Abwesenheit wirft es nie.
  • Store-Semantik. ManifestStore ist eine unveränderliche, geordnete Liste von Root-JumbfBox-Instanzen, gemäß dem Manifest-Store-Modell von C2PA 2.1 §11.1.1: ein JUMBF-Container, der ein oder mehrere Manifeste aggregiert, per URI adressierbar. Er stellt keine Accessoren auf Claim-Ebene bereit. Die Box-Reihenfolge bleibt erhalten und ist für die Round-Trip-Gleichheit tragend.
  • Härtungs-Caps. JumbfBoxParser weist Eingaben, die irgendeinen Cap überschreiten, bedingungslos zurück: Größe pro Box über 64 MiB, kumulativer Store über 128 MiB, Verschachtelung tiefer als 8 Ebenen oder mehr als 4096 Kinder in einer Superbox. Kein Policy-Flag deaktiviert diese Caps. Engere Caps sind für speicherbeschränkte Prozesse per Konstruktor injizierbar.
  • Strukturelle Zurückweisung. Der Parser weist zudem fail-closed zurück: LBox = 0 (BMFF bis EOF), LBox = 1 (XLBox 64-Bit-Länge), ein LBox kleiner als der 8-Byte-Header, Trunkierung über die verbleibende Eingabe hinaus, TBox-Bytes außerhalb von druckbarem ASCII (0x20–0x7E), Offset-Wiedereintritt (Zyklen) und nicht-exakte Kind-Kachelung einer Superbox-Payload. Er gibt niemals einen teilweise konstruierten Graphen zurück.
  • Superbox-Routing. TBox-Werte in SUPERBOX_TBOXES werden rekursiv als Kind-Sequenzen geparst; jedes andere TBox ist ein Blatt mit einer opaken Payload. cbor wird aus Parser-Sicherheitsgründen bewusst als Blatt behandelt; vorgelagerte Schichten parsen seine Payload bei Bedarf neu.
  • Prozess-Gate. Feature::PREVIEW_C2PA_DRAFT ist standardmäßig aus. isEnabled() gibt nur dann true zurück, wenn NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT exakt der Zeichenkette 1 entspricht. Der Lesevorgang erfolgt bei jedem Aufruf live; nichts wird memoisiert.
  • Fail-closed-Konstruktion. new ExperimentalC2paEmbedder() wirft LogicException, solange das Gate aus ist. Die Meldung nennt das Flag, die Umgebungsvariable sowie die fixierte Entwurfs-SHA und das Datum. Ein Aufrufer kann die Entwurfssynthese nicht versehentlich erreichen.
  • Syntheseform. buildManifestStore() emittiert eine c2pa-Superbox, die ein c2ma-Manifest enthält, welches wiederum einen c2as-Assertion-Store (eine c2pa.hash.data-Assertion) und einen c2cl-Claim hält. Die Assertion erfasst eine SHA-256-Hash-Assertion über $sourceBytes; da die c2cs Claim Signature Box weggelassen wird und die Ausgabe unsigniert ist, ist dies KEINE C2PA-Hard-Binding und kein Provenienz-Verdikt — sie folgt nur der strukturellen Form, die §9.1 beschreibt. Description-Box-Payloads tragen eine Typ-UUID, Toggles 0x03 und ein null-terminiertes UTF-8-Label, gemäß C2PA 2.1 §11.1.4.1.1–11.1.4.1.2.
  • Keine Claim Signature. Die c2cs-Box — gemäß C2PA 2.1 §11.1.4.4 eine einzelne CBOR-Content-Box mit dem Label c2pa.signature — wird absichtlich aus dem synthetisierten Store weggelassen. Die Ausgabe ist konstruktionsbedingt unsigniert. Dies ist die Profilregion, die am wahrscheinlichsten vor dem Einfrieren durch die Arbeitsgruppe abweicht.
  • Entwurfs-Pin, keine BC-Garantie. Das synthetisierte Wire-Format ist auf SPEC_PIN_SHA (4e2afed8…, datiert 2026-04-26) von c2pa-org/specifications fixiert. Es kann sich ohne Vorankündigung ändern und trägt keine Rückwärtskompatibilitätsgarantie.
  • Ehrlichkeitsinvariante. C2paCapabilityStatus::current() verdrahtet generallyAvailable und conformanceClaimed fest auf false. Keine Konfiguration und kein Umgebungs-Flag kippt einen der beiden Booleans. Nur previewEnabled spiegelt das Gate wider; maturity ist der nicht-beanspruchende Token preview-draft.
  • Das Setzen der Gate-Variable auf 0, true, yes, on oder eine leere Zeichenkette lässt das Gate aus. Nur die exakte Zeichenkette 1 aktiviert es.
  • putenv()-Änderungen werden beim nächsten isEnabled()-Aufruf wirksam, weil der Lesevorgang live ist. Ein mitten im Prozess umgeschaltetes Gate wird sofort beobachtet.
  • extract() unterscheidet zwei Ergebnisse: null, wenn kein Store vorhanden ist (günstig, ausnahmefrei), und eine geworfene C2paException-Unterklasse, wenn ein Store vorhanden, aber feindlich oder fehlerhaft ist. Abwesenheit ist niemals ein Fehler; Vorhandensein plus Fehlerhaftigkeit ist es immer.
  • JumbfBoxParser::parse('') gibt die leere Liste zurück. Ein leerer, aber vorhandener ManifestStore round-trippt zu sich selbst; die Naht kollabiert ihn nicht zu null.
  • Das Einbetten eines leeren Store DARF die Eingabe unverändert zurückgeben. Der Nahtvertrag erlaubt dieses No-Op, schreibt es aber nicht vor.
  • Handgebaute JumbfBox-Graphen durchlaufen dieselbe Härtung zur Konstruktionszeit: TBox-Längen- und ASCII-Prüfungen, den Tiefen-Cap, die Kind-Tiefen-Invariante, die Payload-oder-Kinder-Ausschließlichkeitsregel und den Größen-Cap pro Box. Eine handgebaute Bombe scheitert bei der Konstruktion, nicht zur Embed-Zeit.
  • Jede Parser-Ausnahme trägt strukturierte Felder — capKind/observed/cap, offset oder kind — sodass Telemetrie keine Meldungszeichenketten scrapen muss. Alle Unterklassen erweitern C2paException (selbst eine RuntimeException), was der übergreifende Catch-Typ ist.
  • Der Parser-Docblock verbietet das stille Verschlucken dieser Ausnahmen; Konsumenten legen sie offen oder mappen sie mit Absicht um.
  • buildManifestStore() enkodiert JSON-Payloads mit JSON_THROW_ON_ERROR; eine $producer-Zeichenkette, die kein gültiges UTF-8 ist, scheitert mit \JsonException, bevor irgendeine Box gebaut wird.
  • Ein wohlgeformtes extract()-Ergebnis ist nur eine strukturelle Aussage. Es gibt auf dieser Oberfläche nirgends eine Claim-Validierung, keine Signaturverifizierung und keine Vertrauensbewertung. Erkennung ist kein Provenienz-Verdikt.
  • Kein Signaturschlüssel, kein Zertifikat und keine COSE-Struktur wird von dieser Oberfläche verarbeitet. Die einzige kryptografische Operation ist ein SHA-256-Content-Hash innerhalb des gegateten Synthesepfades.
AussageStandardKlausel
Manifeste serialisieren in einen JUMBF-Store, der mehrere Manifeste hält, per URI adressierbar.C2PA 2.1§11.1.1 (p63.b)
Description-Box-Labels sind null-terminiertes UTF-8 mit ausgeschlossenen Bereichen; Toggles sind für alle Description-Boxen definiert.C2PA 2.1§11.1.4.1.1–11.1.4.1.2 (p63.a)
Die Claim Signature Box trägt das Label c2pa.signature, ist vom Typ c2cs und hält eine einzelne CBOR-Content-Box.C2PA 2.1§11.1.4.4 (p63.c)
Eine Hard-Binding bindet ein Manifest kryptografisch an sein Asset und legt Modifikation offen — die unsignierte Hash-Assertion der Vorschau erfüllt diese Latte NICHT.C2PA 2.1§9.1 (p57)

Alle Klauseln sind paraphrasiert. NextPDF gibt normativen Text nicht wieder. NextPDF besitzt keine Zertifizierung und erteilt keine. Die obigen Aussagen sind Aussagen zur strukturellen Ausrichtung über Box-Layout, Labels und Bindungen — sie sind keine Konformitätstest-Ergebnisse, keine Drittparteien-Attestierungen und kein C2PA- oder ISO-Konformitätsanspruch. Das C2PA-PDF-Profil ist nicht finalisiert; das synthetisierte Wire-Format verfolgt einen fixierten Entwurfs-Commit. C2paCapabilityStatus kodiert diese Haltung im Code: generallyAvailable und conformanceClaimed sind in jeder Konfiguration false. Die Ausgabe dieser Oberfläche ist kein verifizierbares Content Credential, und in NextPDF existiert kein Verifizierungspfad.

  • Die JUMBF-Box-Grammatik, die der Parser implementiert (4-Byte-Big-Endian-LBox, 4-Byte-ASCII-TBox, Payload; Superboxen verschachteln Kind-Boxen), folgt ISO 19566-5; dieser Standard liegt außerhalb des zitierten Korpus, sodass das Parser-Verhalten aus der Produktquelle abgeleitet ist, nicht aus einer Spec-Zitierung.

  • Halten Sie das Gate in der Produktion aus. Die Entwurfssynthese fügt keine dauerhafte Fähigkeit hinzu; die emittierten Bytes sind vergänglich und sollten neu eingebettet werden, sobald ein stabiler Adapter ausgeliefert wird.

  • Prüfen Sie ExperimentalC2paEmbedder::SPEC_PIN_SHA gegen den Entwurfs-Commit, den Ihre Pipeline erwartet. Führen Sie composer c2pa:draft-status in CI aus (Exit 0 frisch, 1 Soft-Warnung, 2 Hard-Fail), um Pin-Veraltung zu erkennen.

  • Behandeln Sie C2paCapabilityStatus::current() als die einzige Wahrheitsquelle, wenn Sie den C2PA-Status in Tooling oder UI darstellen. Geben Sie seine Booleans nicht von Hand wieder; summary() ist sicher für Logs und Status-Endpunkte.

  • Fangen Sie C2paException als übergreifenden Typ, wenn Sie extract() oder parse() konsumieren. Mappen Sie die vier Unterklassen anhand ihrer strukturierten Felder auf getrennte Telemetrie-Zähler.

  • Injizieren Sie engere Caps über den JumbfBoxParser-Konstruktor für speicherbeschränkte Verifizierer-Prozesse; die Standardwerte sind großzügige Produktions-Caps.

  • C2paCapabilityStatus::__construct() ist öffentlich, sodass eine handgebaute Instanz beliebige Booleans tragen kann. Eine solche Instanz ist nur ein Wertobjekt; sie ändert kein Verhalten.

Diese Seite dokumentiert nur extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namespace-Pfade, Hilfsklassen, Mechanismustabellen, Runbook-Dateinamen und Ticket-Präfixe sind außerhalb des Geltungsbereichs.