Ir al contenido
getnextpdf.com

Pro ediciónestabilidad: Experimental

Vista previa de C2PA — Referencia detallada

Esta página es la referencia a nivel de contrato de la superficie de vista previa de C2PA (Content Credentials) en NextPDF Pro. Cubre cinco símbolos públicos de NextPDF\Pro\Compliance\C2pa: la SPI C2paManifestEmbedder, el objeto de valor ManifestStore, el JumbfBoxParser, el descriptor C2paCapabilityStatus y el Experimental\ExperimentalC2paEmbedder acotado por puerta. También documenta la puerta Feature::PREVIEW_C2PA_DRAFT y su variable de entorno, NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT.

La superficie es experimental y está dividida en dos capas. El punto de unión estable — ManifestStore, C2paManifestEmbedder, JumbfBoxParser — es siempre alcanzable y transporta los bytes del Manifest Store en ambos sentidos. La síntesis de manifiestos de borrador reside únicamente en ExperimentalC2paEmbedder y está desactivada por defecto. El perfil C2PA-PDF no ha sido finalizado por el grupo de trabajo; el formato de transmisión sintetizado está fijado a un commit de borrador. No se hace ninguna afirmación de conformidad, no existe ruta de verificación y activar el indicador de vista previa no puede crear ninguna de las dos. La vista orientada a tareas reside en la página de capacidad.

Esta capacidad se distribuye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Un despliegue sin ese derecho no carga las clases de la capacidad. Compare ediciones y obtenga una licencia.

La licencia activa la superficie de conformidad de Pro en su conjunto. La superficie de C2PA dentro de ella sigue siendo una vista previa con independencia del nivel de licencia. La síntesis de borrador requiere además la puerta de proceso documentada aquí; una licencia de Pro por sí sola nunca la habilita.

SímboloParámetrosComportamiento por defectoDevuelveLanza o falla conNotas
C2paManifestEmbedderSPI de incrustación/extracción solo de bytes; sin E/S; sin síntesis de reclamacionesInterfaz de unión congelada y neutral respecto al proveedor.
C2paManifestEmbedder::embed()string $pdfBytes, ManifestStore $storeIncrusta $store->toBytes() en la ubicación declarada por el perfil; un Store vacío PUEDE ir y volver como una operación nulastring nuevos bytes de PDFC2paException ante cualquier fallo de incrustación (Store sobredimensionado, PDF inválido, colisión de ubicación del perfil)Las implementaciones nunca mutan ni retienen los bytes de entrada.
C2paManifestEmbedder::extract()string $pdfBytesSonda de detección barata; el caso sin Store apenas asigna memoria?ManifestStore (null si no hay coincidencia)Subclase de C2paException cuando hay un Store presente pero viola un invariante de refuerzoUn Store no nulo ya ha superado el refuerzo de JumbfBoxParser.
ManifestStore::fromBoxes()array $boxes (list<JumbfBox>)Envuelve una lista ordenada de cajas validada por el analizadorselfNo lanza por sí mismo; la construcción manual de JumbfBox aplica el mismo refuerzoEl constructor es privado; el orden de las cajas es determinante para la igualdad de ida y vuelta.
ManifestStore::empty()ningunoStore con cero cajas raízselfNo lanzatoBytes() de un Store vacío es la cadena vacía.
ManifestStore::isEmpty()ningunoComprueba si hay cero cajas raízboolNo lanza
ManifestStore::toBytes()ningunoConcatena las serializaciones de las cajas raízstringNo lanzaEsta secuencia de bytes es lo que escribe un incrustador.
ManifestStore::size()ningunoLongitud en bytes de toBytes()int (>= 0)No lanza
JumbfBoxParser::__construct()tres sustituciones de límite opcionalesLímites de producción: 64 MiB por caja, 128 MiB en total, 4096 hijos por supercajaJumbfBoxParserNo lanzaEl límite de profundidad está fijado en MAX_DEPTH (8) y no es ajustable por el constructor.
JumbfBoxParser::parse()string $bytesValida y materializa las cajas raíz; una entrada vacía produce []list<JumbfBox>JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException, MalformedJumbfExceptionSin estado; nunca devuelve un grafo parcial; las llamadas concurrentes sobre una instancia son seguras.
C2paCapabilityStatus::__construct()seis campos nombrados de solo lecturaConstruye una instancia de descriptor arbitrariaC2paCapabilityStatusNo lanzacurrent() es el constructor canónico.
C2paCapabilityStatus::current()ningunoLee la puerta en vivo; fija en código los booleanos de reclamaciónC2paCapabilityStatusNo lanzagenerallyAvailable y conformanceClaimed son siempre false.
C2paCapabilityStatus::summary()ningunoTexto de estado de una líneastringNo lanzaRedactado de forma que no transmite ninguna afirmación de GA ni de conformidad.
Featureenum respaldado por cadena, 1 casoÚnico caso PREVIEW_C2PA_DRAFT; constante ENV_PREVIEW_C2PA_DRAFTcaso de enumNada al acceder al casoPuerta de estabilidad acotada; distinta del derecho de licencia.
Feature::isEnabled()ningunoLee getenv() en vivo; comparación estricta contra la cadena 1boolNo lanzaCon la variable ausente o cualquier otro valor, incluidos 0, true, yes, está desactivada.
ExperimentalC2paEmbedder::__construct()ningunoComprobación de puerta con cierre ante fallo en tiempo de construcciónExperimentalC2paEmbedderLogicException cuando Feature::PREVIEW_C2PA_DRAFT está desactivadaNo existe repliegue silencioso.
ExperimentalC2paEmbedder::buildManifestStore()string $sourceBytes, string $producer (no vacío)Construye un Store con forma de borrador que enlaza $sourceBytes mediante SHA-256ManifestStore\JsonException ante fallo de codificación de la carga útil; subclases de C2paException de la construcción de cajasOmite la caja de firma de reclamación c2cs; la salida está sin firmar por construcción.
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
  • División en dos capas. El punto de unión estable (ManifestStore, C2paManifestEmbedder, JumbfBoxParser) es siempre alcanzable. La síntesis de borrador existe únicamente en NextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedder tras la puerta desactivada por defecto. La extracción y el transporte de bytes nunca requieren la puerta; la síntesis siempre la requiere.
  • Invariantes del punto de unión. El contrato de C2paManifestEmbedder es solo de bytes: ningún objeto PDF en memoria cruza el punto de unión, las implementaciones no realizan E/S de red ni de sistema de archivos, y el punto de unión nunca ensambla por sí mismo las aserciones de reclamación. extract() devuelve null para señalar la ausencia; nunca lanza por ausencia.
  • Semántica del Store. ManifestStore es una lista ordenada e inmutable de instancias raíz de JumbfBox, conforme al modelo de Manifest Store de C2PA 2.1 §11.1.1: un contenedor JUMBF que agrega uno o más manifiestos, direccionables por URI. No expone accesores a nivel de reclamación. El orden de las cajas se preserva y es determinante para la igualdad de ida y vuelta.
  • Límites de refuerzo. JumbfBoxParser rechaza de forma incondicional las entradas que superan cualquier límite: tamaño por caja superior a 64 MiB, store acumulado superior a 128 MiB, anidamiento de más de 8 niveles de profundidad, o más de 4096 hijos en una supercaja. Ningún indicador de política desactiva estos límites. Se pueden inyectar límites más estrictos por el constructor para procesos con memoria restringida.
  • Rechazo estructural. El analizador también rechaza, con cierre ante fallo: LBox = 0 (BMFF hasta EOF), LBox = 1 (longitud XLBox de 64 bits), un LBox menor que la cabecera de 8 bytes, truncamiento más allá de la entrada restante, bytes de TBox fuera del ASCII imprimible (0x20–0x7E), reingreso de desplazamiento (ciclos) y teselado no exacto de los hijos de la carga útil de una supercaja. Nunca devuelve un grafo construido parcialmente.
  • Enrutamiento de supercajas. Los valores de TBox que están en SUPERBOX_TBOXES se analizan recursivamente como secuencias de hijos; cualquier otro TBox es una hoja con una carga útil opaca. cbor se trata deliberadamente como una hoja por seguridad del analizador; las capas superiores vuelven a analizar su carga útil cuando es necesario.
  • Puerta de proceso. Feature::PREVIEW_C2PA_DRAFT está desactivada por defecto. isEnabled() devuelve true solo cuando NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT es igual a la cadena 1 exactamente. La lectura es en vivo en cada llamada; no se memoriza nada.
  • Construcción con cierre ante fallo. new ExperimentalC2paEmbedder() lanza LogicException mientras la puerta está desactivada. El mensaje nombra el indicador, la variable de entorno y el SHA y la fecha del borrador fijados. Quien la invoque no puede alcanzar la síntesis de borrador de forma accidental.
  • Forma de la síntesis. buildManifestStore() emite una supercaja c2pa que contiene un manifiesto c2ma, el cual alberga un almacén de aserciones c2as (una aserción c2pa.hash.data) y una reclamación c2cl. La aserción registra una aserción de hash SHA-256 sobre $sourceBytes; como la caja de firma de reclamación c2cs se omite y la salida está sin firmar, esto NO es un enlace fuerte de C2PA ni un veredicto de procedencia — solo sigue la forma estructural que describe §9.1. Las cargas útiles de las cajas de descripción llevan un UUID de tipo, los conmutadores 0x03 y una etiqueta UTF-8 terminada en nulo, conforme a C2PA 2.1 §11.1.4.1.1–11.1.4.1.2.
  • Sin firma de reclamación. La caja c2cs — conforme a C2PA 2.1 §11.1.4.4 una única caja de contenido CBOR etiquetada c2pa.signature — se omite intencionadamente del Store sintetizado. La salida está sin firmar por construcción. Esta es la región del perfil que se considera más probable que varíe antes de la congelación del grupo de trabajo.
  • Fijación de borrador, sin garantía de compatibilidad. El formato de transmisión sintetizado está fijado a SPEC_PIN_SHA (4e2afed8…, con fecha 2026-04-26) de c2pa-org/specifications. Puede cambiar sin previo aviso y no ofrece ninguna garantía de compatibilidad con versiones anteriores.
  • Invariante de honestidad. C2paCapabilityStatus::current() fija en código generallyAvailable y conformanceClaimed en false. Ninguna configuración ni indicador de entorno cambia ninguno de los dos booleanos. Solo previewEnabled refleja la puerta; maturity es el token no reivindicativo preview-draft.
  • Ajustar la variable de la puerta a 0, true, yes, on o una cadena vacía deja la puerta desactivada. Solo la cadena exacta 1 la activa.
  • Los cambios de putenv() surten efecto en la siguiente llamada a isEnabled() porque la lectura es en vivo. Una puerta conmutada a mitad de proceso se observa de inmediato.
  • extract() distingue dos resultados: null cuando no hay ningún Store presente (barato, sin excepciones) y una subclase de C2paException lanzada cuando hay un Store presente pero hostil o malformado. La ausencia nunca es un error; la presencia con malformación siempre lo es.
  • JumbfBoxParser::parse('') devuelve la lista vacía. Un ManifestStore vacío pero presente va y vuelve a sí mismo; el punto de unión no lo colapsa a null.
  • Incrustar un Store vacío PUEDE devolver la entrada sin cambios. El contrato del punto de unión permite esta operación nula pero no la exige.
  • Los grafos de JumbfBox construidos a mano ejecutan el mismo refuerzo en tiempo de construcción: comprobaciones de longitud y ASCII de TBox, el límite de profundidad, el invariante de profundidad de hijos, la regla de exclusividad entre carga útil e hijos, y el límite de tamaño por caja. Una bomba construida a mano falla en la construcción, no en el momento de la incrustación.
  • Cada excepción del analizador lleva campos estructurados — capKind/observed/cap, offset o kind — de modo que la telemetría no tiene que raspar cadenas de mensaje. Todas las subclases extienden C2paException (que a su vez es una RuntimeException), que es el tipo de captura paraguas.
  • El docblock del analizador prohíbe tragarse silenciosamente estas excepciones; los consumidores las hacen aflorar o las reasignan con intención.
  • buildManifestStore() codifica las cargas útiles JSON con JSON_THROW_ON_ERROR; una cadena $producer que no sea UTF-8 válido falla con \JsonException antes de construir caja alguna.
  • Un resultado bien formado de extract() es solo una afirmación estructural. No hay validación de reclamaciones, ni verificación de firma, ni evaluación de confianza en ningún punto de esta superficie. El reconocimiento no es un veredicto de procedencia.
  • Esta superficie no procesa ninguna clave de firma, certificado ni estructura COSE. La única operación criptográfica es un hash de contenido SHA-256 dentro de la ruta de síntesis acotada.
AfirmaciónEstándarCláusula
Los manifiestos se serializan en un único store JUMBF que alberga múltiples manifiestos, direccionables por URI.C2PA 2.1§11.1.1 (p63.b)
Las etiquetas de las cajas de descripción son UTF-8 terminadas en nulo con rangos excluidos; los conmutadores están definidos para todas las cajas de descripción.C2PA 2.1§11.1.4.1.1–11.1.4.1.2 (p63.a)
La caja de firma de reclamación está etiquetada c2pa.signature, tipada c2cs, y contiene una única caja de contenido CBOR.C2PA 2.1§11.1.4.4 (p63.c)
Un enlace fuerte ata criptográficamente un manifiesto a su activo y expone las modificaciones — la aserción de hash sin firmar de la vista previa NO alcanza este listón.C2PA 2.1§9.1 (p57)

Todas las cláusulas están parafraseadas. NextPDF no reproduce texto normativo. NextPDF no posee certificación alguna ni la concede. Las afirmaciones anteriores son afirmaciones de alineamiento estructural sobre la disposición de las cajas, las etiquetas y los enlaces — no son resultados de pruebas de conformidad, ni atestaciones de terceros, ni una afirmación de conformidad con C2PA o ISO. El perfil C2PA-PDF no está finalizado; el formato de transmisión sintetizado sigue un commit de borrador fijado. C2paCapabilityStatus codifica esta postura en el código: generallyAvailable y conformanceClaimed son false en toda configuración. La salida de esta superficie no es una Content Credential verificable, y no existe ruta de verificación en NextPDF.

  • La gramática de cajas JUMBF que implementa el analizador (LBox big-endian de 4 bytes, TBox ASCII de 4 bytes, carga útil; las supercajas anidan cajas hijas) sigue ISO 19566-5; ese estándar queda fuera del corpus citado, por lo que el comportamiento del analizador se fundamenta en el código fuente del producto, no en una cita de especificación.

  • Mantenga la puerta desactivada en producción. La síntesis de borrador no añade ninguna capacidad duradera; los bytes emitidos son transitorios y deberían volver a incrustarse una vez que se distribuya un adaptador estable.

  • Verifique ExperimentalC2paEmbedder::SPEC_PIN_SHA contra el commit de borrador que su canalización espera. Ejecute composer c2pa:draft-status en CI (salida 0 fresco, 1 aviso leve, 2 fallo grave) para detectar el desfase de la fijación.

  • Trate C2paCapabilityStatus::current() como la única fuente de verdad al exponer el estado de C2PA en herramientas o interfaz de usuario. No reformule sus booleanos a mano; summary() es seguro para registros y puntos de estado.

  • Capture C2paException como el tipo paraguas al consumir extract() o parse(). Asigne las cuatro subclases a contadores de telemetría distintos usando sus campos estructurados.

  • Inyecte límites más estrictos a través del constructor de JumbfBoxParser para procesos verificadores con memoria restringida; los valores por defecto son límites de producción generosos.

  • C2paCapabilityStatus::__construct() es público, así que una instancia construida a mano puede llevar booleanos arbitrarios. Tal instancia es solo un objeto de valor; no altera ningún comportamiento.

Esta página documenta únicamente el comportamiento observable externamente y la superficie de API pública soportada. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de ticket quedan fuera de alcance.