THotPDF Preflight Report Methods

Sintaxis

type
  THPDFPreflightFormat = (pfText, pfJSON, pfHTML, pfCSV);

function CreatePreflightReport(const SourceFile: TFileName): AnsiString;
function CreatePreflightReport(
  const SourceFile: TFileName;
  const Password  : AnsiString): AnsiString;
function CreatePreflightReport(
  const SourceFile: TFileName;
  const Password  : AnsiString;
  const Format    : THPDFPreflightFormat): AnsiString;
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName);
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName;
  const Password  : AnsiString);
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName;
  const Password  : AnsiString;
  const Format    : THPDFPreflightFormat);
function ValidatePDFVT(
  const SourceFile: TFileName;
  out Report      : AnsiString): Boolean;
function ValidatePDFVT(
  const SourceFile: TFileName;
  const Password  : AnsiString;
  out Report      : AnsiString): Boolean;
procedure EmbedPreflightReportInPDF(
  const SourceFile: TFileName;
  const TargetFile: TFileName);
procedure EmbedPreflightReportInPDF(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  const Password  : AnsiString);
function LoadAndValidatePreflightReport(
  const EmbeddedFile  : TFileName;
  out OriginalReport: AnsiString;
  out CurrentReport : AnsiString): Boolean;
function LoadAndValidatePreflightReport(
  const EmbeddedFile  : TFileName;
  const Password      : AnsiString;
  out OriginalReport: AnsiString;
  out CurrentReport : AnsiString): Boolean;
function ComparePreflightReports(
  const ReportA: AnsiString;
  const ReportB: AnsiString): AnsiString;
function RepairPDFFromPreflightReport(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  out RepairsApplied: AnsiString): Boolean;
function RepairPDFFromPreflightReport(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  const Password  : AnsiString;
  out RepairsApplied: AnsiString): Boolean;
function AggregatePreflightReports(
  const Reports: array of AnsiString): AnsiString;
type
  THPDFPreflightProfile = record
    DisableChecks  : AnsiString;
    DisableWarnings: AnsiString;
    DisableHints   : Boolean;
  end;
function LoadPreflightProfile(
  const ProfileFile: TFileName): THPDFPreflightProfile;
function ApplyPreflightProfile(
  const Report : AnsiString;
  const Profile: THPDFPreflightProfile): AnsiString;
function ValidatePreflightProfile(
  const Profile: THPDFPreflightProfile;
  out UnknownNames: AnsiString): Boolean;
function GetBuiltInPreflightProfile(
  const Name: AnsiString): THPDFPreflightProfile;
procedure SavePreflightProfile(
  const Profile    : THPDFPreflightProfile;
  const ProfileFile: TFileName);
function CreatePreflightReportWithProfile(
  const SourceFile : TFileName;
  const Password   : AnsiString;
  const ProfileFile: TFileName;
  const Format     : THPDFPreflightFormat): AnsiString;
function MergePreflightProfiles(
  const A, B: THPDFPreflightProfile): THPDFPreflightProfile;
function DiffPreflightProfiles(
  const A, B  : THPDFPreflightProfile;
  out OnlyInA: AnsiString;
  out OnlyInB: AnsiString): Boolean;
procedure EmbedPreflightReportAsXMP(
  const SourceFile: TFileName;
  const TargetFile: TFileName);
procedure EmbedPreflightReportAsXMP(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  const Password  : AnsiString);
function ConvertPreflightReportToVeraPDFStyle(
  const Report: AnsiString): AnsiString;

Descripción

CreatePreflightReport lee un PDF de entrada y devuelve un informe de texto con comprobaciones estructurales ligeras. Las sobrecargas con contraseña usan la ruta de carga existente compatible con contraseñas para PDF cifrados admitidos SavePreflightReport escribe el mismo informe en un archivo de texto de destino

ValidatePDFVT ejecuta una pasada de validación enfocada en PDF/VT y devuelve True solo cuando están presentes los marcadores y estructuras requeridos. El informe de texto devuelto comprueba la declaración XMP pdfvtid:GTS_PDFVTVersion, el namespace de metadatos PDF/VT, la fecha de modificación PDF/VT y la coincidencia de xmp:ModifyDate, el marcador base PDF/X, la ausencia de cifrado, el output intent PDF/X, DPartRoot del catálogo, DPartRootNode, NodeNameList, la presencia de partes de documento, el recuento de páginas cargables y la cobertura DPart a nivel de página. Las propiedades de fecha PDF/VT y XMP pueden escribirse como texto de elemento o como atributos RDF en un elemento rdf:Description

El informe comprueba el encabezado PDF, el marcador EOF, si el marcador final %%EOF está cerca del final del archivo, el último offset startxref, si ese offset apunta a una tabla xref o a un xref stream, los recuentos de marcadores %%EOF y startxref, el balance de marcadores de revisión y el orden del marcador final, el marcador trailer o XRef stream, el recuento de páginas cargables, el estado de cifrado, el catálogo, el árbol de páginas, el marcador de objeto de página, MediaBox, la referencia al diccionario de información, la referencia raíz, el recuento de objetos indirectos, el recuento de definiciones de objetos indirectos, el número de objeto más alto, el recuento de números de objeto duplicados, la unicidad de números de objeto, el recuento de objetos de catálogo, el recuento de objetos del árbol de páginas, el recuento de objetos de página, el recuento de páginas declarado por el árbol de páginas, la consistencia entre recuento de árbol de páginas y páginas cargables, la consistencia entre objetos de página y páginas cargables, el balance de stream y endstream, la cobertura de entradas /Length de stream, el recuento de tablas xref, el recuento de subsecciones xref, los recuentos de entradas de tabla xref, los recuentos de entradas xref libres y en uso, el recuento de filas xref malformadas, la validez de filas xref, la cobertura xref frente a números de objeto, el recuento de xref streams, el recuento de object streams, el recuento de trailers, /Size de trailer, si /Size de trailer cubre el número de objeto más alto, las referencias indirectas /Root y /Info de trailer, si esos objetos referenciados están definidos, si /Root de trailer apunta a un objeto de catálogo, el recuento de entradas del array /ID de trailer y su estructura por pares, la presencia de /Root, /Info, /ID y /Encrypt en el trailer, el recuento estimado de actualizaciones incrementales, el estado de linearization, las cajas de página cargadas, el recuento de campos de formulario, el recuento de diccionarios de recursos, el recuento de recursos de fuente, el recuento de programas de fuente incrustados (/FontFile, /FontFile2, /FontFile3), el recuento de image XObject, el recuento de form XObject, el recuento de recursos ColorSpace, el recuento de anotaciones y los subrecuentos de anotaciones widget/link, los recuentos de uso de cadenas de filtros para FlateDecode, DCTDecode, CCITTFaxDecode, JBIG2Decode, LZWDecode, ASCIIHexDecode, ASCII85Decode, RunLengthDecode y JPXDecode, la cobertura de incrustación de fuentes, la consistencia del recuento de anotaciones, las pistas de cumplimiento PDF/A / PDF/X / PDF/UA / Tagged PDF / transparencia, las flags de características seleccionadas, las advertencias de JavaScript o acciones (cubriendo todo el conjunto de acciones PDF 1.7 sec 12.6.4: GoTo*, Thread, URI, Sound, Movie, Hide, Named, SubmitForm, ResetForm, ImportData, SetOCGState, Rendition, Trans y GoTo3DView, además de las comprobaciones heredadas JavaScript / Launch / OpenAction / AdditionalActions / EmbeddedFile / RichMedia y las advertencias de exclusión mutua PDF/A), los totales de advertencias y un resumen global pass/fail Estos helpers están pensados como comprobaciones rápidas en proceso antes de entregar archivos a validadores externos de estándares; no sustituyen a un motor completo de validación preflight PDF/A, PDF/X, PDF/UA o ISO 32000

La sobrecarga Format acepta pfText (ruta de texto plano predeterminada, estable byte a byte con las sobrecargas heredadas), pfJSON (documento JSON apto para CI) o pfHTML (informe HTML autónomo listo para dashboards, con CSS inline y filas coloreadas por severidad). La salida JSON agrupa entradas en campos superiores input, size, pdfVersion y xrefStyle, además de arrays checks, info, hints y warnings, y un objeto summary con valores failed, warnings y result El codificador JSON integrado escapa ", \ y bytes de control; las secuencias de bytes UTF-8 pasan sin cambios

Cada entrada de checks, hints y warnings lleva un campo opcional spec que nombra la cláusula ISO a la que apunta el diagnóstico (por ejemplo ISO 32000-1 sec 7.5.5 para comprobaciones relacionadas con trailer, ISO 19005-1 sec 6.6.2 para la advertencia de exclusión mutua PDF/A con JavaScript). El mapeo cubre cada comprobación, pista y advertencia emitida por el informe hasta v2.122.0. Un JSON Schema formal (draft 2020-12) que describe la estructura de salida pfJSON se publica en Docs/preflight-schema.json para que los consumidores downstream puedan validar la salida antes de analizarla

EmbedPreflightReportInPDF escribe una copia del PDF de origen en TargetFile con el informe preflight heredado en formato de texto anexado después del último %%EOF como líneas de comentario estilo PDF (cada línea prefijada con ). Los lectores PDF ignoran los bytes anexados porque quedan fuera del grafo de objetos, pero los flujos de archivo, editores de texto y herramientas estilo grep aún pueden mostrar el informe incrustado para una auditoría posterior. El grafo de objetos original, la tabla de referencias cruzadas y el trailer no se modifican

LoadAndValidatePreflightReport extrae el informe que EmbedPreflightReportInPDF anexó previamente, vuelve a ejecutar el algoritmo preflight actual sobre los bytes de origen anteriores al bloque de comentarios incrustado y compara los valores InputFingerprint. La función devuelve True cuando ambas huellas coinciden, lo que indica que el informe incrustado todavía describe el archivo tal como existe en disco. Cuando la validación falla, los llamadores pueden inspeccionar OriginalReport y CurrentReport para comparar qué cambió

ComparePreflightReports emite un cuerpo similar a unified diff para dos informes. Las líneas compartidas aparecen con un prefijo de dos espacios, las líneas exclusivas de ReportA llevan el prefijo y las líneas exclusivas de ReportB llevan el prefijo . El algoritmo está ajustado para la salida key/value bien formada producida por CreatePreflightReport, donde el orden de líneas es determinista; no es una implementación LCS de propósito general, pero produce diffs compactos y legibles para el caso típico de informes casi sin cambios

RepairPDFFromPreflightReport aplica un subconjunto conservador de reparaciones a nivel de bytes a un PDF dañado: elimina los bytes finales que siguen al marcador final %%EOF y agrega un %%EOF faltante cuando no hay ninguno presente. La función devuelve True cuando se aplicó al menos una reparación; RepairsApplied enumera las reparaciones con una línea por cambio. Las reparaciones del grafo de objetos (reconstruir tablas xref, parchear longitudes de stream, corregir diccionarios trailer) quedan intencionalmente fuera de alcance porque esas correcciones pueden hacer que un archivo parcialmente recuperable sea menos recuperable; use una herramienta dedicada de recuperación PDF para daños más profundos

AggregatePreflightReports toma un array de informes por archivo y produce un único resumen de lote. Cada entrada del array se analiza para extraer sus campos Input, Size y Summary; el agregado emite una línea por archivo más totales del número de informes aprobados, fallidos y con advertencias, el total de bytes escaneados y los recuentos globales de resultado. Es útil para pipelines CI y bucles de shell que procesan un directorio de PDF y necesitan un único resumen conciso al final

LoadPreflightProfile y ApplyPreflightProfile permiten a los llamadores adaptar la salida del informe sin volver a ejecutar el análisis. El archivo de perfil usa un formato estilo INI con tres secciones opcionales: [disable-checks] enumera nombres de comprobaciones que se deben suprimir; [disable-warnings] enumera nombres de advertencias que se deben suprimir; y [options] acepta hints=false para suprimir todas las líneas Hint. Después del filtrado, la línea Summary se recalcula para que las entradas suprimidas ya no contribuyan a los totales Failed y Warnings; el resto del informe pasa sin cambios

ValidatePreflightProfile recorre las listas DisableChecks y DisableWarnings de un perfil cargado e informa cualquier nombre que la implementación preflight actual no reconozca Es útil para detectar archivos de perfil creados contra una versión más nueva o más antigua de HotPDF que, de otro modo, no desactivarían nada silenciosamente porque los nombres no coinciden con ninguna comprobación o advertencia emitida

GetBuiltInPreflightProfile devuelve registros de perfil listos para usar para flujos comunes. Nombres reconocidos (sin distinguir mayúsculas): default / '' devuelve un perfil vacío; compact desactiva todas las líneas Hint para informes más cortos; silent-actions desactiva todas las advertencias de acciones PDF 1.7 sec 12.6.4 más EmbeddedFile y RichMedia, pensado para flujos que incrustan multimedia o acciones interactivas intencionalmente y no quieren que el informe preflight las marque. Los nombres desconocidos también devuelven un perfil vacío

SavePreflightProfile escribe un registro THPDFPreflightProfile de vuelta a un archivo INI en el mismo formato que consume LoadPreflightProfile. Las dos funciones son inversas exactas para perfiles bien formados, por lo que los llamadores pueden construir un flujo 'cargar preset, ajustar, guardar': P := GetBuiltInPreflightProfile('compact'), editar P.DisableChecks y luego SavePreflightProfile(P, 'tuned.ini') para reutilizarlo más tarde

CreatePreflightReportWithProfile es un wrapper de conveniencia único que compone los elementos existentes CreatePreflightReport, LoadPreflightProfile, ApplyPreflightProfile y los conversores de formato para que un llamador que ya tiene un PDF de origen, una contraseña opcional, un archivo de perfil y un formato de destino pueda hacer una sola llamada en lugar de encadenar cuatro. Pasar ProfileFile vacío omite el paso de perfil

MergePreflightProfiles devuelve la unión deduplicada de dos perfiles: DisableChecks y DisableWarnings recopilan nombres de ambas entradas, y DisableHints es el OR lógico Es útil para superponer un preset sobre ajustes específicos del proyecto

DiffPreflightProfiles informa la diferencia estructural entre dos perfiles. Devuelve True cuando son equivalentes; de lo contrario devuelve False con OnlyInA y OnlyInB rellenados con líneas separadas por saltos de línea con la forma check:<name>, warn:<name> u option:hints=false, que describen qué entradas son exclusivas de cada lado

EmbedPreflightReportAsXMP es una variante más adecuada para archivo de EmbedPreflightReportInPDF: escribe una copia del PDF de origen con el informe preflight anexado como bloque de comentarios estilo PDF cuyo payload es XMP / RDF (xmlns:hotpdf="http://www.loslab.com/hotpdf/preflight/") Cada línea del informe se convierte en un elemento hotpdf:<name> con la severidad llevada como atributo en las filas de comprobación Las herramientas conscientes de XMP que escanean un archivo en busca de marcadores xpacket pueden mostrar el informe incrustado; los lectores PDF siguen ignorando los bytes anexados porque quedan fuera del grafo de objetos. Esto no pretende ser una integración XMP conforme a la especificación: el payload XMP no se referencia desde la entrada /Metadata del catálogo, por lo que los lectores XMP que solo siguen la referencia del catálogo no lo verán

ConvertPreflightReportToVeraPDFStyle moldea un informe preflight de HotPDF en un documento JSON que sigue el esquema amplio de la salida de validación de veraPDF, con un campo superior profile, un array jobs que contiene itemDetails / taskResult / validationResult, y un array ruleViolations bajo validationResult.details. Tiene estilo HotPDF, no compatibilidad wire con veraPDF; el objetivo es permitir que las herramientas downstream que ya consumen JSON de veraPDF se adapten a la salida de HotPDF con un remapeo mínimo de nombres de campo, en lugar de aprender una disposición de datos completamente distinta

Ejemplo

var
  PDF: THotPDF;
begin
  PDF := THotPDF.Create(nil);
  try
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.txt');
    PDF.SavePreflightReport('Encrypted.pdf', 'EncryptedReport.txt', 'user-password');
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.json', '', pfJSON);
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.html', '', pfHTML);
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.csv', '', pfCSV);
    PDF.EmbedPreflightReportInPDF('Input.pdf', 'Input-with-report.pdf');
    if not PDF.LoadAndValidatePreflightReport(
      'Input-with-report.pdf', OriginalReport, CurrentReport)
    then
      WriteLn('Embedded preflight report no longer matches the source.');
  finally
    PDF.Free;
  end;
end;

Véase también