Lewati ke konten
getnextpdf.com

Pro edisistabilitas: Eksperimental

Pratinjau C2PA — Referensi Mendalam

Halaman ini adalah referensi tingkat kontrak untuk permukaan pratinjau C2PA (Content Credentials) di NextPDF Pro. Halaman ini mencakup lima simbol publik di NextPDF\Pro\Compliance\C2pa: SPI C2paManifestEmbedder, value object ManifestStore, JumbfBoxParser, deskriptor C2paCapabilityStatus, dan Experimental\ExperimentalC2paEmbedder yang di-gate. Halaman ini juga mendokumentasikan gate Feature::PREVIEW_C2PA_DRAFT dan variabel lingkungannya, NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT.

Permukaan ini bersifat eksperimental dan terbagi menjadi dua lapisan. Seam yang stabil — ManifestStore, C2paManifestEmbedder, JumbfBoxParser — selalu dapat dijangkau dan membawa byte Manifest Store ke dua arah. Sintesis draf manifest hanya berada di ExperimentalC2paEmbedder dan bersifat default-off. Profil C2PA-PDF belum difinalisasi oleh working group; format wire yang disintesis dipin ke sebuah commit draf. Tidak ada klaim kesesuaian yang dibuat, tidak ada jalur verifikasi, dan mengaktifkan flag pratinjau tidak dapat menciptakan keduanya. Tampilan berorientasi tugas berada di halaman kapabilitas.

Kapabilitas ini dikirimkan dalam NextPDF Pro (nextpdf/pro) dan aktif dengan envelope lisensi tier Pro. Deployment tanpa entitlement tersebut tidak memuat kelas-kelas kapabilitas ini. Bandingkan edisi dan dapatkan lisensi.

Lisensi mengaktifkan permukaan compliance Pro secara keseluruhan. Permukaan C2PA di dalamnya tetap menjadi pratinjau tanpa memandang tier lisensi. Sintesis draf selain itu memerlukan gate proses yang didokumentasikan di sini; lisensi Pro saja tidak pernah mengaktifkannya.

SimbolParameterPerilaku defaultMengembalikanMelempar atau gagal denganCatatan
C2paManifestEmbedderSPI embed/extract hanya-byte; tanpa I/O; tanpa sintesis claimInterface seam yang dibekukan dan netral-vendor.
C2paManifestEmbedder::embed()string $pdfBytes, ManifestStore $storeMenyematkan $store->toBytes() pada lokasi yang dideklarasikan profil; Store kosong DAPAT round-trip sebagai no-opstring byte PDF baruC2paException pada setiap kegagalan embed (Store terlalu besar, PDF tidak valid, kolisi lokasi-profil)Implementasi tidak pernah memutasi atau menyimpan byte input.
C2paManifestEmbedder::extract()string $pdfBytesProbe deteksi murah; kasus tanpa-Store hampir tidak mengalokasikan apa pun?ManifestStore (null jika tidak ada)Subclass C2paException ketika Store ada tetapi melanggar invarian pengerasanStore non-null telah lolos pengerasan JumbfBoxParser.
ManifestStore::fromBoxes()array $boxes (list<JumbfBox>)Membungkus daftar box terurut yang telah divalidasi parserselfTidak melempar sendiri; konstruksi JumbfBox buatan tangan menerapkan pengerasan yang samaKonstruktor bersifat privat; urutan box menjadi penentu untuk kesetaraan round-trip.
ManifestStore::empty()tidak adaStore dengan nol root boxselfTidak melempartoBytes() dari Store kosong adalah string kosong.
ManifestStore::isEmpty()tidak adaMenguji apakah nol root boxboolTidak melempar
ManifestStore::toBytes()tidak adaMenggabungkan serialisasi root-boxstringTidak melemparUrutan byte inilah yang ditulis oleh embedder.
ManifestStore::size()tidak adaPanjang byte dari toBytes()int (>= 0)Tidak melempar
JumbfBoxParser::__construct()tiga override cap opsionalCap produksi: 64 MiB per box, 128 MiB total, 4096 anak per superboxJumbfBoxParserTidak melemparCap kedalaman ditetapkan pada MAX_DEPTH (8) dan tidak dapat disetel melalui konstruktor.
JumbfBoxParser::parse()string $bytesMemvalidasi dan mewujudkan root box; input kosong menghasilkan []list<JumbfBox>JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException, MalformedJumbfExceptionStateless; tidak pernah mengembalikan graf parsial; panggilan konkuren pada satu instance aman.
C2paCapabilityStatus::__construct()enam field readonly bernamaMembangun instance deskriptor sembarangC2paCapabilityStatusTidak melemparcurrent() adalah konstruktor kanonik.
C2paCapabilityStatus::current()tidak adaMembaca gate secara live; men-hard-code boolean claimC2paCapabilityStatusTidak melempargenerallyAvailable dan conformanceClaimed selalu false.
C2paCapabilityStatus::summary()tidak adaTeks status satu barisstringTidak melemparDiformulasikan agar tidak membawa klaim GA atau kesesuaian.
Featureenum string-backed, 1 caseCase tunggal PREVIEW_C2PA_DRAFT; konstanta ENV_PREVIEW_C2PA_DRAFTcase enumTidak ada apa pun saat akses caseGate stabilitas terlingkup; berbeda dari entitlement lisensi.
Feature::isEnabled()tidak adaMembaca getenv() secara live; perbandingan ketat terhadap string 1boolTidak melemparVariabel yang tidak ada atau nilai lain apa pun, termasuk 0, true, yes, dianggap off.
ExperimentalC2paEmbedder::__construct()tidak adaPemeriksaan gate fail-closed pada waktu konstruksiExperimentalC2paEmbedderLogicException ketika Feature::PREVIEW_C2PA_DRAFT offTidak ada fallback diam-diam.
ExperimentalC2paEmbedder::buildManifestStore()string $sourceBytes, string $producer (non-empty)Membangun Store berbentuk draf yang mengikat $sourceBytes via SHA-256ManifestStore\JsonException pada kegagalan encode payload; subclass C2paException dari konstruksi boxMenghilangkan box Claim Signature c2cs; output tidak ditandatangani secara konstruksi.
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
  • Pembagian dua-lapisan. Seam yang stabil (ManifestStore, C2paManifestEmbedder, JumbfBoxParser) selalu dapat dijangkau. Sintesis draf hanya ada di NextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedder di balik gate yang default-off. Ekstraksi dan pembawaan byte tidak pernah memerlukan gate; sintesis selalu memerlukannya.
  • Invarian seam. Kontrak C2paManifestEmbedder bersifat hanya-byte: tidak ada objek PDF in-memory yang melintasi seam, implementasi tidak melakukan I/O jaringan atau filesystem, dan seam tidak pernah merakit asersi claim sendiri. extract() mengembalikan null untuk menandakan ketiadaan; ia tidak pernah melempar untuk ketiadaan.
  • Semantik Store. ManifestStore adalah daftar terurut immutable dari instance root JumbfBox, sesuai model Manifest Store C2PA 2.1 §11.1.1: satu kontainer JUMBF yang mengagregasi satu atau lebih manifest, dapat dialamatkan via URI. Ia tidak mengekspos accessor tingkat-claim. Urutan box dipertahankan dan menjadi penentu untuk kesetaraan round-trip.
  • Cap pengerasan. JumbfBoxParser tanpa syarat menolak input yang melampaui cap apa pun: ukuran per-box di atas 64 MiB, store kumulatif di atas 128 MiB, nesting lebih dalam dari 8 tingkat, atau lebih dari 4096 anak dalam satu superbox. Tidak ada flag kebijakan yang menonaktifkan cap ini. Cap yang lebih ketat dapat di-inject melalui konstruktor untuk proses yang terbatas memori.
  • Penolakan struktural. Parser juga menolak, fail-closed: LBox = 0 (BMFF hingga-EOF), LBox = 1 (XLBox panjang 64-bit), LBox yang lebih kecil dari header 8-byte, pemotongan melewati sisa input, byte TBox di luar ASCII printable (0x20–0x7E), re-entry offset (siklus), dan tiling anak yang tidak eksak dari payload superbox. Ia tidak pernah mengembalikan graf yang terkonstruksi sebagian.
  • Perutean superbox. Nilai TBox dalam SUPERBOX_TBOXES di-parse secara rekursif sebagai urutan anak; setiap TBox lain adalah leaf dengan payload buram. cbor sengaja diperlakukan sebagai leaf demi keamanan parser; lapisan hulu me-re-parse payload-nya saat diperlukan.
  • Gate proses. Feature::PREVIEW_C2PA_DRAFT off secara default. isEnabled() mengembalikan true hanya ketika NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT persis sama dengan string 1. Pembacaan bersifat live pada setiap panggilan; tidak ada yang di-memoise.
  • Konstruksi fail-closed. new ExperimentalC2paEmbedder() melempar LogicException selama gate off. Pesannya menyebutkan flag, variabel lingkungan, serta SHA dan tanggal draf yang dipin. Pemanggil tidak dapat menjangkau sintesis draf secara tidak sengaja.
  • Bentuk sintesis. buildManifestStore() memancarkan superbox c2pa yang berisi satu manifest c2ma, yang menampung sebuah assertion store c2as (satu asersi c2pa.hash.data) dan sebuah claim c2cl. Asersi tersebut mencatat asersi hash SHA-256 atas $sourceBytes; karena box Claim Signature c2cs dihilangkan dan output tidak ditandatangani, ini BUKAN hard binding C2PA atau verdict provenance — ia hanya mengikuti bentuk struktural yang dijelaskan §9.1. Payload Description-box membawa UUID tipe, toggle 0x03, dan label UTF-8 yang diakhiri null, sesuai C2PA 2.1 §11.1.4.1.1–11.1.4.1.2.
  • Tanpa Claim Signature. Box c2cs — sesuai C2PA 2.1 §11.1.4.4 sebuah box konten CBOR tunggal berlabel c2pa.signature — sengaja dihilangkan dari Store yang disintesis. Output tidak ditandatangani secara konstruksi. Ini adalah region profil yang dinilai paling mungkin bergeser sebelum pembekuan oleh working group.
  • Pin draf, tanpa jaminan BC. Format wire yang disintesis dipin ke SPEC_PIN_SHA (4e2afed8…, bertanggal 2026-04-26) dari c2pa-org/specifications. Ia dapat berubah tanpa pemberitahuan dan tidak membawa jaminan backwards-compatibility.
  • Invarian kejujuran. C2paCapabilityStatus::current() men-hard-code generallyAvailable dan conformanceClaimed menjadi false. Tidak ada konfigurasi atau flag lingkungan yang membalik salah satu boolean tersebut. Hanya previewEnabled yang mencerminkan gate; maturity adalah token non-klaim preview-draft.
  • Mengatur variabel gate ke 0, true, yes, on, atau string kosong membiarkan gate off. Hanya string persis 1 yang mengaktifkannya.
  • Perubahan putenv() berlaku pada panggilan isEnabled() berikutnya karena pembacaan bersifat live. Gate yang di-toggle di tengah proses langsung teramati.
  • extract() membedakan dua hasil: null ketika tidak ada Store (murah, bebas-eksepsi), dan subclass C2paException yang dilempar ketika Store ada tetapi berbahaya atau malformed. Ketiadaan tidak pernah menjadi error; keberadaan plus malformasi selalu menjadi error.
  • JumbfBoxParser::parse('') mengembalikan daftar kosong. ManifestStore yang kosong tetapi ada round-trip menjadi dirinya sendiri; seam tidak meruntuhkannya menjadi null.
  • Menyematkan Store kosong DAPAT mengembalikan input tanpa perubahan. Kontrak seam mengizinkan no-op ini tetapi tidak mewajibkannya.
  • Graf JumbfBox buatan tangan menjalankan pengerasan yang sama pada waktu konstruksi: pemeriksaan panjang dan ASCII TBox, cap kedalaman, invarian kedalaman-anak, aturan eksklusivitas payload-atau-anak, dan cap ukuran per-box. Bomb buatan tangan gagal pada konstruksi, bukan pada waktu embed.
  • Setiap eksepsi parser membawa field terstruktur — capKind/observed/cap, offset, atau kind — sehingga telemetri tidak menyisir string pesan. Semua subclass memperluas C2paException (yang sendirinya adalah RuntimeException), yang merupakan tipe catch payung.
  • Docblock parser melarang penelanan eksepsi ini secara diam-diam; konsumen memunculkannya atau me-remap-nya dengan maksud jelas.
  • buildManifestStore() meng-encode payload JSON dengan JSON_THROW_ON_ERROR; string $producer yang bukan UTF-8 valid gagal dengan \JsonException sebelum box apa pun dibangun.
  • Hasil extract() yang well-formed hanyalah pernyataan struktural. Tidak ada validasi claim, tidak ada verifikasi tanda tangan, dan tidak ada evaluasi trust di mana pun pada permukaan ini. Pengenalan bukanlah verdict provenance.
  • Tidak ada kunci penandatanganan, sertifikat, atau struktur COSE yang diproses oleh permukaan ini. Satu-satunya operasi kriptografis adalah hash konten SHA-256 di dalam jalur sintesis yang di-gate.
KlaimStandarKlausa
Manifest diserialisasi ke dalam satu store JUMBF yang menampung banyak manifest, dapat dialamatkan via URI.C2PA 2.1§11.1.1 (p63.b)
Label Description-box adalah UTF-8 yang diakhiri null dengan rentang yang dikecualikan; toggle didefinisikan untuk semua Description box.C2PA 2.1§11.1.4.1.1–11.1.4.1.2 (p63.a)
Box Claim Signature berlabel c2pa.signature, bertipe c2cs, dan menampung satu box konten CBOR.C2PA 2.1§11.1.4.4 (p63.c)
Hard binding mengikat manifest ke asetnya secara kriptografis dan mengekspos modifikasi — asersi hash tak-bertanda-tangan pada pratinjau ini TIDAK memenuhi standar ini.C2PA 2.1§9.1 (p57)

Semua klausa diparafrasakan. NextPDF tidak mereproduksi teks normatif. NextPDF tidak memegang sertifikasi apa pun dan tidak memberikan apa pun. Pernyataan di atas adalah pernyataan penyelarasan-struktural tentang tata letak box, label, dan binding — bukan hasil uji kesesuaian, bukan atestasi pihak ketiga, dan bukan klaim kesesuaian C2PA atau ISO. Profil C2PA-PDF belum difinalisasi; format wire yang disintesis melacak sebuah commit draf yang dipin. C2paCapabilityStatus mengenkode postur ini dalam kode: generallyAvailable dan conformanceClaimed adalah false dalam setiap konfigurasi. Output dari permukaan ini bukan Content Credential yang dapat diverifikasi, dan tidak ada jalur verifikasi di NextPDF.

  • Grammar box JUMBF yang diimplementasikan parser (LBox big-endian 4-byte, TBox ASCII 4-byte, payload; superbox menyarangkan child box) mengikuti ISO 19566-5; standar tersebut berada di luar korpus yang dikutip, sehingga perilaku parser digrounding dari sumber produk, bukan kutipan spesifikasi.

  • Biarkan gate off di produksi. Sintesis draf tidak menambah kapabilitas yang tahan lama; byte yang dipancarkan bersifat transien dan sebaiknya di-re-embed setelah adapter yang stabil dikirimkan.

  • Asersikan ExperimentalC2paEmbedder::SPEC_PIN_SHA terhadap commit draf yang diharapkan pipeline Anda. Jalankan composer c2pa:draft-status di CI (exit 0 segar, 1 soft-warn, 2 hard-fail) untuk mendeteksi keusangan pin.

  • Perlakukan C2paCapabilityStatus::current() sebagai satu-satunya sumber kebenaran saat menampilkan status C2PA di tooling atau UI. Jangan menyatakan ulang boolean-nya secara manual; summary() aman untuk log dan endpoint status.

  • Tangkap C2paException sebagai tipe payung saat mengonsumsi extract() atau parse(). Petakan keempat subclass ke counter telemetri yang berbeda menggunakan field terstrukturnya.

  • Inject cap yang lebih ketat melalui konstruktor JumbfBoxParser untuk proses verifier yang terbatas memori; default-nya adalah cap produksi yang murah hati.

  • C2paCapabilityStatus::__construct() bersifat publik, sehingga instance buatan tangan dapat membawa boolean sembarang. Instance semacam itu hanyalah value object; ia tidak mengubah perilaku apa pun.

Halaman ini mendokumentasikan hanya perilaku yang dapat diamati secara eksternal dan permukaan API publik yang didukung. Jalur namespace internal, kelas helper, tabel mekanisme, nama file runbook, dan prefiks tiket berada di luar cakupan.