Code samples
Here you'll find some samples to get you started with the Pdf Tools SDK.
Sign documents
Sign a PDF and add a visual appearance on an unsigned signature field.
1static void AddAppearanceSignatureField(string certificateFile, string password, string appConfigFile, string inPath, string outPath)
2{
3 // Create a session to the built-in cryptographic provider
4 using var session = new PdfTools.Crypto.Providers.BuiltIn.Provider();
5
6 // Create signature configuration from PFX (or P12) file
7 using var pfxStr = File.OpenRead(certificateFile);
8 var signature = session.CreateSignatureFromCertificate(pfxStr, password);
9
10 // Open input document
11 using var inStr = File.OpenRead(inPath);
12 using var inDoc = Document.Open(inStr);
13
14 // Choose first signature field
15 foreach (var field in inDoc.SignatureFields)
16 {
17 if (field != null)
18 {
19 signature.FieldName = field.FieldName;
20 break;
21 }
22 }
23
24 // Create stream for output file
25 using var outStr = File.Create(outPath);
26
27 // Create appearance from either an XML or a json file
28 using var appStream = File.OpenRead(appConfigFile);
29 if (Path.GetExtension(appConfigFile) == ".xml")
30 signature.Appearance = Appearance.CreateFromXml(appStream);
31 else
32 signature.Appearance = Appearance.CreateFromJson(appStream);
33
34 signature.Appearance.PageNumber = 1;
35 signature.Appearance.CustomTextVariables.Add("company", "Daily Planet");
36
37 // Sign the input document
38 using var outDoc = new Signer().Sign(inDoc, signature, outStr);
39}
1private static void sign(String certificateFile, String password, String appConfigFile, String inPath, String outPath) throws Exception
2{
3 try (
4 // Create a session to the built-in cryptographic provider
5 Provider session = new Provider();
6
7 // Open certificate file
8 FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY);
9
10 // Open input document
11 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
12 Document inDoc = Document.open(inStr);)
13 {
14 // Create signature configuration from PFX (or P12) file
15 SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);
16
17 // Choose first signature field
18 for (int i = 0; i < inDoc.getSignatureFields().size(); i++) {
19 if (inDoc.getSignatureFields().get(i) != null) {
20 signature.setFieldName(inDoc.getSignatureFields().get(i).getFieldName());
21 break;
22 }
23 }
24
25 try (
26 // Create appearance from either an XML or a json file
27 FileStream appConfigStr = new FileStream(appConfigFile, FileStream.Mode.READ_ONLY))
28 {
29 if (appConfigFile.toLowerCase().endsWith(".xml"))
30 signature.setAppearance(Appearance.createFromXml(appConfigStr));
31 else
32 signature.setAppearance(Appearance.createFromJson(appConfigStr));
33
34 signature.getAppearance().setPageNumber(1);
35 signature.getAppearance().getCustomTextVariables().put("company", "Daily Planet");
36
37 try(
38 // Create a stream for the output file
39 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
40
41 // Sign the input document
42 Document outDoc = new Signer().sign(inDoc, signature, outStr))
43 {
44 }
45 }
46 }
47}
Add a document time-stamp to a PDF
1static void AddTimestamp(Uri timeStampUrl, string inPath, string outPath)
2{
3 // Create a session to the built-in cryptographic provider
4 using var session = new BuiltIn.Provider();
5 session.TimestampUrl = timeStampUrl;
6
7 // Create time-stamp configuration
8 var timestamp = session.CreateTimestamp();
9
10 // Open input document
11 using var inStr = File.OpenRead(inPath);
12 using var inDoc = Document.Open(inStr);
13
14 // Create stream for output file
15 using var outStr = File.Create(outPath);
16
17 // Add the document time-stamp
18 using var outDoc = new Signer().AddTimestamp(inDoc, timestamp, outStr);
19}
1private static void addTimestamp(URI timeStampUrl, String inPath, String outPath) throws Exception
2{
3 // Create a session to the built-in cryptographic provider
4 try (Provider session = new Provider())
5 {
6 // Configure URL of the trusted time-stamp authority (TSA)
7 session.setTimestampUrl(timeStampUrl);
8
9 // Create time-stamp configuration
10 TimestampConfiguration timestamp = session.createTimestamp();
11
12 try (
13 // Open input document
14 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
15 Document inDoc = Document.open(inStr);
16
17 // Create output stream
18 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
19
20 // Add the document time-stamp
21 Document outDoc = new Signer().addTimestamp(inDoc, timestamp, outStr))
22 {
23 }
24 }
25}
Certify a PDF
1static void Certify(string certificateFile, string password, string inPath, string outPath)
2{
3 // Create a session to the built-in cryptographic provider
4 using var session = new BuiltIn.Provider();
5
6 // Create signature configuration from PFX (or P12) file
7 using var pfxStr = File.OpenRead(certificateFile);
8 var signature = session.CreateSignatureFromCertificate(pfxStr, password);
9
10 // Embed validation information to enable the long term validation (LTV) of the signature (default)
11 signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument;
12
13 // Open input document
14 using var inStr = File.OpenRead(inPath);
15 using var inDoc = Document.Open(inStr);
16
17 // Create stream for output file
18 using var outStr = File.Create(outPath);
19
20 // Add a document certification (MDP) signature
21 // Optionally, the access permissions can be set.
22 using var outDoc = new Signer().Certify(inDoc, signature, outStr);
23}
1private static void certify(String certificateFile, String password, String inPath, String outPath) throws Exception
2{
3 try (
4 // Create a session to the built-in cryptographic provider
5 Provider session = new Provider();
6
7 // Open certificate file
8 FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY))
9 {
10 // Create signature configuration from PFX (or P12) file
11 SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);
12
13 // Embed validation information to enable the long term validation (LTV) of the signature (default)
14 signature.setValidationInformation(com.pdftools.crypto.ValidationInformation.EMBED_IN_DOCUMENT);
15
16 try (
17 // Open input document
18 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
19 Document inDoc = Document.open(inStr);
20
21 // Create output stream
22 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
23
24 // Add a document certification (MDP) signature
25 // Optionally, the access permissions can be set.
26 Document outDoc = new Signer().certify(inDoc, signature, outStr))
27 {
28 }
29 }
30}
Sign a PDF using a PFX soft certificate
1static void Sign(string certificateFile, string password, string inPath, string outPath)
2{
3 // Create a session to the built-in cryptographic provider
4 using var session = new BuiltIn.Provider();
5
6 // Create signature configuration from PFX (or P12) file
7 using var pfxStr = File.OpenRead(certificateFile);
8 var signature = session.CreateSignatureFromCertificate(pfxStr, password);
9
10 // Embed validation information to enable the long term validation (LTV) of the signature (default)
11 signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument;
12
13 // Open input document
14 using var inStr = File.OpenRead(inPath);
15 using var inDoc = Document.Open(inStr);
16
17 // Create stream for output file
18 using var outStr = File.Create(outPath);
19
20 // Sign the input document
21 using var outDoc = new Signer().Sign(inDoc, signature, outStr);
22}
1private static void sign(String certificateFile, String password, String inPath, String outPath) throws Exception
2{
3 try (
4 // Create a session to the built-in cryptographic provider
5 Provider session = new Provider();
6
7 // Open certificate file
8 FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY))
9 {
10 // Create signature configuration from PFX (or P12) file
11 SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);
12
13 // Embed validation information to enable the long term validation (LTV) of the signature (default)
14 signature.setValidationInformation(com.pdftools.crypto.ValidationInformation.EMBED_IN_DOCUMENT);
15
16 try (
17 // Open input document
18 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
19 Document inDoc = Document.open(inStr);
20
21 // Create a stream for the output file
22 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
23
24 // Sign the input document
25 Document outDoc = new Signer().sign(inDoc, signature, outStr))
26 {
27 }
28 }
29}
Add a document time-stamp to a PDF using the GlobalSign Digital Signing Service
1// Configure the SSL client certificate to connect to the service
2var httpClientHandler = new HttpClientHandler();
3using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.cer"))
4 using (var sslClientKey = File.OpenRead(@"C:\path\to\privateKey.key"))
5 httpClientHandler.SetClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");
6
7// Connect to the GlobalSign Digital Signing Service
8using var session = new GlobalSignDss.Session(new Uri("https://emea.api.dss.globalsign.com:8443"), "***insert api_key***", "***insert api_secret***", httpClientHandler);
9
10// Add a document time-stamp to a PDF
11AddTimestamp(session, inPath, outPath);
1static void AddTimestamp(GlobalSignDss.Session session, string inPath, string outPath)
2{
3 // Create time-stamp configuration
4 var timestamp = session.CreateTimestamp();
5
6 // Open input document
7 using var inStr = File.OpenRead(inPath);
8 using var inDoc = Document.Open(inStr);
9
10 // Create stream for output file
11 using var outStr = File.Create(outPath);
12
13 // Add the document time-stamp
14 using var outDoc = new Signer().AddTimestamp(inDoc, timestamp, outStr);
15}
1// Configure the SSL client certificate to connect to the service
2HttpClientHandler httpClientHandler = new HttpClientHandler();
3try (
4 FileStream sslClientCert = new FileStream("C:/path/to/clientcert.cer", FileStream.Mode.READ_ONLY);
5 FileStream sslClientKey = new FileStream("C:/path/to/privateKey.key", FileStream.Mode.READ_ONLY))
6{
7 httpClientHandler.setClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");
8}
9
10// Connect to the GlobalSign Digital Signing Service
11try (Session session = new Session(new URI("https://emea.api.dss.globalsign.com:8443"),
12 "***insert api_key***", "***insert api_secret***",
13 httpClientHandler))
14{
15 // Add a document time-stamp to a PDF
16 addTimestamp(session, inPath, outPath);
17}
1private static void addTimestamp(Session session, String inPath, String outPath) throws Exception
2{
3 // Create time-stamp configuration
4 TimestampConfiguration timestamp = session.createTimestamp();
5
6 try (
7 // Open input document
8 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
9 Document inDoc = Document.open(inStr);
10
11 // Create output stream
12 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
13
14 // Add the document time-stamp
15 Document outDoc = new Signer().addTimestamp(inDoc, timestamp, outStr))
16 {
17 }
18}
Sign a PDF using the GlobalSign Digital Signing Service
1// Configure the SSL client certificate to connect to the service
2var httpClientHandler = new HttpClientHandler();
3using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.cer"))
4 using (var sslClientKey = File.OpenRead(@"C:\path\to\privateKey.key"))
5 httpClientHandler.SetClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");
6
7// Connect to the GlobalSign Digital Signing Service
8using var session = new GlobalSignDss.Session(new Uri("https://emea.api.dss.globalsign.com:8443"), "***insert api_key***", "***insert api_secret***", httpClientHandler);
9
10// Sign a PDF document
11Sign(session, commonName, inPath, outPath);
1static void Sign(GlobalSignDss.Session session, string commonName, string inPath, string outPath)
2{
3 // Create a signing certificate for an account with a dynamic identity
4 var identity = JsonSerializer.Serialize(new { subject_dn = new { common_name = commonName } });
5 var signature = session.CreateSignatureForDynamicIdentity(identity);
6
7 // Embed validation information to enable the long term validation (LTV) of the signature (default)
8 signature.ValidationInformation = PdfTools.Crypto.ValidationInformation.EmbedInDocument;
9
10 // Open input document
11 using var inStr = File.OpenRead(inPath);
12 using var inDoc = Document.Open(inStr);
13
14 // Create stream for output file
15 using var outStr = File.Create(outPath);
16
17 // Sign the document
18 using var outDoc = new Signer().Sign(inDoc, signature, outStr);
19}
1// Configure the SSL client certificate to connect to the service
2HttpClientHandler httpClientHandler = new HttpClientHandler();
3try (
4 FileStream sslClientCert = new FileStream("C:/path/to/clientcert.cer", FileStream.Mode.READ_ONLY);
5 FileStream sslClientKey = new FileStream("C:/path/to/privateKey.key", FileStream.Mode.READ_ONLY))
6{
7 httpClientHandler.setClientCertificateAndKey(sslClientCert, sslClientKey, "***insert password***");
8}
9
10// Connect to the GlobalSign Digital Signing Service
11try (Session session = new Session(new URI("https://emea.api.dss.globalsign.com:8443"),
12 "***insert api_key***", "***insert api_secret***",
13 httpClientHandler))
14{
15 // Sign a PDF document
16 sign(session, commonName, inPath, outPath);
17}
1private static void sign(Session session, String commonName, String inPath, String outPath) throws Exception
2{
3 // Create a signing certificate for an account with a dynamic identity
4 // This can be re-used to sign multiple documents
5 SignatureConfiguration signature = session.createSignatureForDynamicIdentity(String.format("{ \"subject_dn\" : { \"common_name\" : \"%s\" } }", commonName));
6
7 // Embed validation information to enable the long term validation (LTV) of the signature (default)
8 signature.setValidationInformation(ValidationInformation.EMBED_IN_DOCUMENT);
9
10 try (
11 // Open input document
12 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
13 Document inDoc = Document.open(inStr);
14
15 // Create output stream
16 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
17
18 // Sign the input document
19 Document outDoc = new Signer().sign(inDoc, signature, outStr))
20 {
21 }
22}
Sign a PDF using a PKCS#11 device
1// Load the PKCS#11 driver module (middleware)
2// The module can only be loaded once in the application.
3using var module = Pkcs11.Module.Load(pkcs11Library);
4
5// Create a session to the cryptographic device and log in
6// with the password (pin)
7using var session = module.Devices.GetSingle().CreateSession(password);
8
9// Sign a PDF document
10Sign(session, certificate, inPath, outPath);
1static void Sign(Pkcs11.Session session, string certificate, string inPath, string outPath)
2{
3 // Create the signature configuration
4 // This can be re-used to sign multiple documents
5 var signature = session.CreateSignatureFromName(certificate);
6
7 // Open input document
8 using var inStr = File.OpenRead(inPath);
9 using var inDoc = Document.Open(inStr);
10
11 // Create stream for output file
12 using var outStr = File.Create(outPath);
13
14 // Sign the input document
15 using var outDoc = new Signer().Sign(inDoc, signature, outStr);
16}
1try (
2 // Load the PKCS#11 driver module (middleware)
3 // The module can only be loaded once in the application.
4 Module module = Module.load(pkcs11Library);
5
6 // Create a session to the cryptographic device and log in
7 // with the password (pin)
8 Session session = module.getDevices().getSingle().createSession(password))
9{
10 // Sign a PDF document
11 sign(session, certificate, inPath, outPath);
12}
1private static void sign(Session session, String certificate, String inPath, String outPath) throws Exception
2{
3 // Create the signature configuration
4 // This can be re-used to sign multiple documents
5 SignatureConfiguration signature = session.createSignatureFromName(certificate);
6
7 try (
8 // Open input document
9 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
10 Document inDoc = Document.open(inStr);
11
12 // Create output stream
13 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
14
15 // Sign the input document
16 Document outDoc = new Signer().sign(inDoc, signature, outStr))
17 {
18 }
19}
Add a signature field to a PDF
1static void AddSignatureField(string inPath, string outPath)
2{
3 // Open input document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create empty field appearance that is 6cm by 3cm in size
8 var appearance = Appearance.CreateFieldBoundingBox(Size.cm(6, 3));
9
10 // Add field to last page of document
11 appearance.PageNumber = inDoc.PageCount;
12
13 // Position field
14 appearance.Bottom = Length.cm(3);
15 appearance.Left = Length.cm(6.5);
16
17 // Create a signature field configuration
18 var field = new SignatureFieldOptions(appearance);
19
20 // Create stream for output file
21 using var outStr = File.Create(outPath);
22
23 // Sign the input document
24 using var outDoc = new Signer().AddSignatureField(inDoc, field, outStr);
25}
1private static void addSignatureField(String inPath, String outPath) throws Exception
2{
3 try (
4 // Open input document
5 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
6 Document inDoc = Document.open(inStr))
7 {
8 // Create empty field appearance that is 6cm by 3cm in size
9 var appearance = Appearance.createFieldBoundingBox(new Size(6, 3, Units.CENTIMETRE));
10
11 // Add field to last page of document
12 appearance.setPageNumber(inDoc.getPageCount());
13
14 // Position field
15 appearance.setBottom(new Length(3, Units.CENTIMETRE));
16 appearance.setLeft(new Length(6.5, Units.CENTIMETRE));
17
18 // Create a signature field configuration
19 var field = new SignatureFieldOptions(appearance);
20
21 try (
22 // Create output stream
23 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
24
25 // Sign the input document
26 Document outDoc = new Signer().addSignatureField(inDoc, field, outStr))
27 {
28 }
29 }
30}
Validate the signatures contained an input document
1
2// Helper functions to print signature validation details
3
1static int Validate(string inputFile, string certDir)
2{
3 // Use the default validation profile as a base for further settings
4 var profile = new Default();
5
6 // For offline operation, build a custom trust list from the file system
7 // and disable external revocation checks
8 if (certDir != null && certDir.Length != 0)
9 {
10 Console.WriteLine("Using 'offline' validation mode with custom trust list.");
11 Console.WriteLine();
12
13 // create a CustomTrustList to hold the certificates
14 var ctl = new CustomTrustList();
15
16 // Iterate through files in the certificate directory and add certificates
17 // to the custom trust list
18 if (Directory.Exists(certDir))
19 {
20 var directoryListing = Directory.EnumerateFiles(certDir);
21 foreach (string fileName in directoryListing)
22 {
23 try
24 {
25 using var certStr = File.OpenRead(fileName);
26
27 if (fileName.EndsWith(".cer") || fileName.EndsWith(".pem"))
28 {
29 ctl.AddCertificates(certStr);
30 }
31 else if (fileName.EndsWith(".p12") || fileName.EndsWith(".pfx"))
32 {
33 // If a password is required, use addArchive(certStr, password).
34 ctl.AddArchive(certStr);
35 }
36 }
37 catch (Exception e)
38 {
39 Console.WriteLine("Could not add certificate '" + fileName + "' to custom trust list: " + e.Message);
40 }
41 }
42 }
43 else
44 {
45 // Handle the case where dir is not a directory
46 Console.WriteLine("Directory " + certDir + " is missing. No certificates were added to the custom trust list.");
47 }
48 Console.WriteLine();
49
50 // Assign the custom trust list to the validation profile
51 profile.CustomTrustList = ctl;
52
53 // Allow validation from embedded file sources and the custom trust list
54 var vo = profile.ValidationOptions;
55 vo.TimeSource = TimeSource.ProofOfExistence | TimeSource.ExpiredTimeStamp | TimeSource.SignatureTime;
56 vo.CertificateSources = DataSource.EmbedInSignature | DataSource.EmbedInDocument | DataSource.CustomTrustList;
57
58 // Disable revocation checks.
59 profile.SigningCertTrustConstraints.RevocationCheckPolicy = RevocationCheckPolicy.NoCheck;
60 profile.TimeStampTrustConstraints.RevocationCheckPolicy = RevocationCheckPolicy.NoCheck;
61 }
62
63 // Validate ALL signatures in the document (not only the latest)
64 var signatureSelector = SignatureSelector.All;
65
66 // Create the validator object and event listeners
67 var validator = new Validator();
68 validator.Constraint += (s, e) =>
69 {
70 Console.WriteLine(" - " + e.Signature.Name + (e.DataPart.Length > 0 ? (": " + e.DataPart) : "") + ": " +
71 ConstraintToString(e.Indication, e.SubIndication, e.Message));
72 };
73
74 try
75 {
76 using var inStr = File.OpenRead(inputFile);
77 // Open input document
78 // If a password is required, use Open(inStr, password)
79 using var document = Document.Open(inStr);
80
81 // Run the validate method passing the document, profile and selector
82 Console.WriteLine("Validation Constraints");
83 var results = validator.Validate(document, profile, signatureSelector);
84
85 Console.WriteLine();
86 Console.WriteLine("Signatures validated: " + results.Count);
87 Console.WriteLine();
88
89 // Print results
90 foreach (var result in results)
91 {
92 var field = result.SignatureField;
93 Console.WriteLine(field.FieldName + " of " + field.Name);
94 try
95 {
96 Console.WriteLine(" - Revision : " + (field.Revision.IsLatest ? "latest" : "intermediate"));
97 }
98 catch (Exception ex)
99 {
100 Console.WriteLine("Unable to validate document Revision: " + ex.Message);
101 }
102
103 PrintContent(result.SignatureContent);
104 Console.WriteLine();
105 }
106
107 return 0;
108 }
109 catch (Exception ex)
110 {
111 Console.WriteLine("Unable to validate file: " + ex.Message);
112 return 5;
113 }
114}
1private static void PrintContent(SignatureContent content)
2{
3 if(content != null)
4 {
5 Console.WriteLine(" - Validity : " + ConstraintToString(content.Validity));
6 switch (content)
7 {
8 case UnsupportedSignatureContent:
9 break;
10 case CmsSignatureContent signature:
11 {
12 Console.WriteLine(" - Validation: " + signature.ValidationTime + " from " + signature.ValidationTimeSource);
13 Console.WriteLine(" - Hash : " + signature.HashAlgorithm);
14 Console.WriteLine(" - Signing Cert");
15 PrintContent(signature.SigningCertificate);
16 Console.WriteLine(" - Chain");
17 foreach (var cert in signature.CertificateChain)
18 {
19 Console.WriteLine(" - Issuer Cert " + (signature.CertificateChain.IndexOf(cert) + 1));
20 PrintContent(cert);
21 }
22 Console.WriteLine(" - Chain : " + (signature.CertificateChain.IsComplete ? "complete" : "incomplete") + " chain");
23 Console.WriteLine(" Time-Stamp");
24 PrintContent(signature.TimeStamp);
25 break;
26 }
27 case TimeStampContent timeStamp:
28 {
29 Console.WriteLine(" - Validation: " + timeStamp.ValidationTime + " from " + timeStamp.ValidationTimeSource);
30 Console.WriteLine(" - Hash : " + timeStamp.HashAlgorithm);
31 Console.WriteLine(" - Time : " + timeStamp.Date);
32 Console.WriteLine(" - Signing Cert");
33 PrintContent(timeStamp.SigningCertificate);
34 Console.WriteLine(" - Chain");
35 foreach (var cert in timeStamp.CertificateChain)
36 {
37 Console.WriteLine(" - Issuer Cert " + (timeStamp.CertificateChain.IndexOf(cert) + 1));
38 PrintContent(cert);
39 }
40 Console.WriteLine(" - Chain : " + (timeStamp.CertificateChain.IsComplete ? "complete" : "incomplete") + " chain");
41 break;
42 }
43 default:
44 Console.WriteLine("Unsupported signature content type " + content.GetType().Name);
45 break;
46 }
47 }
48 else
49 {
50 Console.WriteLine(" - null");
51 }
52}
1private static void PrintContent(Certificate cert)
2{
3 if(cert != null)
4 {
5 Console.WriteLine(" - Subject : " + cert.SubjectName);
6 Console.WriteLine(" - Issuer : " + cert.IssuerName);
7 Console.WriteLine(" - Validity : " + cert.NotBefore + " - " + cert.NotAfter);
8 try
9 {
10 Console.WriteLine(" - Fingerprint: " + FormatSha1Digest(new BigInteger(SHA1.Create().ComputeHash(cert.RawData)).ToByteArray(), "-"));
11 }
12 catch (Exception ex)
13 {
14 Console.WriteLine(ex.Message);
15 }
16 Console.WriteLine(" - Source : " + cert.Source);
17 Console.WriteLine(" - Validity : " + ConstraintToString(cert.Validity));
18 }
19 else
20 {
21 Console.WriteLine(" - null");
22 }
23}
1private static String ConstraintToString(ConstraintResult constraint)
2{
3 return ConstraintToString(constraint.Indication, constraint.SubIndication, constraint.Message);
4}
1private static String ConstraintToString(Indication indication, SubIndication subIndication, String message)
2{
3 return (indication == Indication.Valid ? "" : (indication == Indication.Indeterminate ? "?" : "!")) + "" +
4 subIndication + " " +
5 message;
6}
1// Helper function to generate a delimited SHA-1 digest string
2private static String FormatSha1Digest(byte[] bytes, String delimiter)
3{
4 var result = new StringBuilder();
5 foreach (byte aByte in bytes)
6 {
7 int number = (int)aByte & 0xff;
8 String hex = number.ToString("X2");
9 result.Append(hex.ToUpper() + delimiter);
10 }
11 return result.ToString().Substring(0, result.Length - delimiter.Length);
12}
1
2// Helper functions to print signature validation details
3
1private static int validate(String inputFile, String certDir)
2{
3 // Use the default validation profile as a base for further settings
4 Profile profile = new Default();
5
6 // For offline operation, build a custom trust list from the file system
7 // and disable external revocation checks
8 if (certDir != null && !certDir.isEmpty())
9 {
10 System.out.println("Using 'offline' validation mode with custom trust list.");
11 System.out.println();
12
13 // create a CustomTrustList to hold the certificates
14 CustomTrustList ctl = new CustomTrustList();
15
16 // Iterate through files in the certificate directory and add certificates
17 // to the custom trust list
18 File dir = new File(certDir);
19 File[] directoryListing = dir.listFiles();
20 if (directoryListing != null)
21 {
22 for (File child : directoryListing)
23 {
24 String fileName = child.getName();
25 try (
26 FileStream certStr = new FileStream(child.getPath(), FileStream.Mode.READ_ONLY))
27 {
28 if (fileName.endsWith(".cer") || fileName.endsWith(".pem"))
29 {
30 ctl.addCertificates(certStr);
31 }
32 else if (fileName.endsWith(".p12") || fileName.endsWith(".pfx"))
33 {
34 // If a password is required, use addArchive(certStr, password).
35 ctl.addArchive(certStr);
36 }
37 }
38 catch (Exception e)
39 {
40 System.out.println("Could not add certificate '" + child.getName() + "' to custom trust list: " + e.getMessage());
41 }
42 }
43 }
44 else
45 {
46 // Handle the case where dir is not a directory
47 System.out.println("Directory " + certDir + " is missing. No certificates were added to the custom trust list.");
48 }
49 System.out.println();
50
51 // Assign the custom trust list to the validation profile
52 profile.setCustomTrustList(ctl);
53
54 // Allow validation from embedded file sources and the custom trust list
55 ValidationOptions vo = profile.getValidationOptions();
56 vo.setTimeSource(EnumSet.of(TimeSource.PROOF_OF_EXISTENCE, TimeSource.EXPIRED_TIME_STAMP, TimeSource.SIGNATURE_TIME));
57 vo.setCertificateSources(EnumSet.of(DataSource.EMBED_IN_SIGNATURE, DataSource.EMBED_IN_DOCUMENT, DataSource.CUSTOM_TRUST_LIST));
58
59 // Disable revocation checks.
60 profile.getSigningCertTrustConstraints().setRevocationCheckPolicy(RevocationCheckPolicy.NO_CHECK);
61 profile.getTimeStampTrustConstraints().setRevocationCheckPolicy(RevocationCheckPolicy.NO_CHECK);
62 }
63
64 // Validate ALL signatures in the document (not only the latest)
65 SignatureSelector signatureSelector = SignatureSelector.ALL;
66
67 // Create the validator object and event listeners
68 Validator validator = new Validator();
69 validator.addConstraintListener(e -> {
70 System.out.println(" - " + e.getSignature().getName() + (e.getDataPart().length() > 0 ? (": " + e.getDataPart()) : "") + ": " +
71 constraintToString(e.getIndication(), e.getSubIndication(), e.getMessage()));
72 });
73
74 try (
75 FileStream inStr = new FileStream(inputFile, FileStream.Mode.READ_ONLY);
76 // Open input document
77 // If a password is required, use open(inStr, password)
78 Document document = Document.open(inStr);
79 )
80 {
81 // Run the validate method passing the document, profile and selector
82 System.out.println("Validation Constraints");
83 ValidationResults results = validator.validate(document, profile, signatureSelector);
84
85 System.out.println();
86 System.out.println("Signatures validated: " + results.size());
87 System.out.println();
88
89 // Print results
90 results.forEach(result -> {
91 SignedSignatureField field = result.getSignatureField();
92 System.out.println(field.getFieldName() + " of " + field.getName());
93 try
94 {
95 System.out.println(" - Revision : " + (field.getRevision().getIsLatest() ? "latest" : "intermediate"));
96 }
97 catch (Exception ex)
98 {
99 System.out.println("Unable to validate document Revision: " + ex.getMessage());
100 }
101
102 printContent(result.getSignatureContent());
103 System.out.println();
104 });
105
106 return 0;
107 }
108 catch (Exception ex)
109 {
110 System.out.println("Unable to validate file: " + ex.getMessage());
111 return 5;
112 }
113}
1private static void printContent(SignatureContent content)
2{
3 if(content != null)
4 {
5 System.out.println(" - Validity : " + constraintToString(content.getValidity()));
6 switch (content.getClass().getSimpleName())
7 {
8 case "UnsupportedSignatureContent":
9 break;
10 case "CmsSignatureContent":
11 {
12 CmsSignatureContent signature = (CmsSignatureContent)content;
13 System.out.println(" - Validation: " + signature.getValidationTime() + " from " + signature.getValidationTimeSource());
14 System.out.println(" - Hash : " + signature.getHashAlgorithm());
15 System.out.println(" - Signing Cert");
16 printContent(signature.getSigningCertificate());
17 System.out.println(" - Chain");
18 signature.getCertificateChain().forEach(cert -> {
19 System.out.println(" - Issuer Cert " + (signature.getCertificateChain().indexOf(cert) + 1));
20 printContent(cert);
21 });
22 System.out.println(" - Chain : " + (signature.getCertificateChain().getIsComplete() ? "complete" : "incomplete") + " chain");
23 System.out.println(" Time-Stamp");
24 printContent(signature.getTimeStamp());
25 break;
26 }
27 case "TimeStampContent":
28 {
29 TimeStampContent timeStamp = (TimeStampContent)content;
30 System.out.println(" - Validation: " + timeStamp.getValidationTime() + " from " + timeStamp.getValidationTimeSource());
31 System.out.println(" - Hash : " + timeStamp.getHashAlgorithm());
32 System.out.println(" - Time : " + timeStamp.getDate());
33 System.out.println(" - Signing Cert");
34 printContent(timeStamp.getSigningCertificate());
35 System.out.println(" - Chain");
36 timeStamp.getCertificateChain().forEach(cert -> {
37 System.out.println(" - Issuer Cert " + (timeStamp.getCertificateChain().indexOf(cert) + 1));
38 printContent(cert);
39 });
40 System.out.println(" - Chain : " + (timeStamp.getCertificateChain().getIsComplete() ? "complete" : "incomplete") + " chain");
41 break;
42 }
43 default:
44 System.out.println("Unsupported signature content type " + content.getClass().getName());
45 break;
46 }
47 }
48 else
49 {
50 System.out.println(" - null");
51 }
52}
1private static void printContent(Certificate cert)
2{
3 if(cert != null)
4 {
5 System.out.println(" - Subject : " + cert.getSubjectName());
6 System.out.println(" - Issuer : " + cert.getIssuerName());
7 System.out.println(" - Validity : " + cert.getNotBefore() + " - " + cert.getNotAfter());
8 try {
9 System.out.println(" - Fingerprint: " + formatSha1Digest(new java.math.BigInteger(1, (MessageDigest.getInstance("SHA-1").digest(cert.getRawData()))).toByteArray(), "-"));
10 } catch (Exception ex) {
11 System.out.println(ex.getMessage());
12 }
13 System.out.println(" - Source : " + cert.getSource());
14 System.out.println(" - Validity : " + constraintToString(cert.getValidity()));
15 }
16 else
17 {
18 System.out.println(" - null");
19 }
20}
1private static String constraintToString(ConstraintResult constraint)
2{
3 return constraintToString(constraint.getIndication(), constraint.getSubIndication(), constraint.getMessage());
4}
1private static String constraintToString(Indication indication, SubIndication subIndication, String message)
2{
3 return (indication == Indication.VALID ? "" : (indication == Indication.INDETERMINATE ? "?" : "!")) + "" +
4 subIndication + " " +
5 message;
6}
1// Helper function to generate a delimited SHA-1 digest string
2private static String formatSha1Digest(byte[] bytes, String delimiter) {
3 StringBuilder result = new StringBuilder();
4 for (byte aByte : bytes) {
5 int decimal = (int) aByte & 0xff;
6 String hex = Integer.toHexString(decimal);
7 if (hex.length() % 2 == 1)
8 hex = "0" + hex;
9 result.append(hex.toUpperCase() + delimiter);
10 }
11 return result.substring(0, result.length() - delimiter.length());
12}
Add a document time-stamp to a PDF using the Swisscom Signing Service
1// Configure the SSL client certificate to connect to the service
2var httpClientHandler = new HttpClientHandler();
3using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.p12"))
4 httpClientHandler.SetClientCertificate(sslClientCert, "***insert password***");
5
6// Connect to the Swisscom Signing Service
7using var session = new SwisscomSigSrv.Session(new Uri("https://ais.swisscom.com"), httpClientHandler);
8
9// Add a document time-stamp to a PDF
10AddTimestamp(session, identity, inPath, outPath);
1static void AddTimestamp(SwisscomSigSrv.Session session, string identity, string inPath, string outPath)
2{
3 // Create time-stamp configuration
4 var timestamp = session.CreateTimestamp(identity);
5
6 // Open input document
7 using var inStr = File.OpenRead(inPath);
8 using var inDoc = Document.Open(inStr);
9
10 // Create stream for output file
11 using var outStr = File.Create(outPath);
12
13 // Add the document time-stamp
14 using var outDoc = new Signer().AddTimestamp(inDoc, timestamp, outStr);
15}
1// Configure the SSL client certificate to connect to the service
2HttpClientHandler httpClientHandler = new HttpClientHandler();
3try (FileStream sslClientCert = new FileStream("C:/path/to/clientcert.p12", FileStream.Mode.READ_ONLY))
4{
5 httpClientHandler.setClientCertificate(sslClientCert, "***insert password***");
6}
7
8// Connect to the Swisscom Signing Service
9try (Session session = new Session(new URI("https://ais.swisscom.com"), httpClientHandler))
10{
11 // Add a document time-stamp to a PDF
12 addTimestamp(session, identity, inPath, outPath);
13}
1private static void addTimestamp(Session session, String identity, String inPath, String outPath) throws Exception
2{
3 // Create time-stamp configuration
4 TimestampConfiguration timestamp = session.createTimestamp(identity);
5
6 try (
7 // Open input document
8 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
9 Document inDoc = Document.open(inStr);
10
11 // Create output stream
12 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
13
14 // Add the document time-stamp
15 Document outDoc = new Signer().addTimestamp(inDoc, timestamp, outStr))
16 {
17 }
18}
Sign a PDF using the Swisscom Signing Service
1// Configure the SSL client certificate to connect to the service
2var httpClientHandler = new HttpClientHandler();
3using (var sslClientCert = File.OpenRead(@"C:\path\to\clientcert.p12"))
4 httpClientHandler.SetClientCertificate(sslClientCert, "***insert password***");
5
6// Connect to the Swisscom Signing Service
7using var session = new SwisscomSigSrv.Session(new Uri("https://ais.swisscom.com"), httpClientHandler);
8
9// Sign a PDF document
10Sign(session, identity, commonName, inPath, outPath);
1static void Sign(SwisscomSigSrv.Session session, string identity, string commonName, string inPath, string outPath)
2{
3 // Create a signing certificate for a static identity
4 var signature = session.CreateSignatureForStaticIdentity(identity, commonName);
5
6 // Embed validation information to enable the long term validation (LTV) of the signature (default)
7 signature.EmbedValidationInformation = true;
8
9 // Open input document
10 using var inStr = File.OpenRead(inPath);
11 using var inDoc = Document.Open(inStr);
12
13 // Create stream for output file
14 using var outStr = File.Create(outPath);
15
16 // Sign the document
17 using var outDoc = new Signer().Sign(inDoc, signature, outStr);
18}
1// Configure the SSL client certificate to connect to the service
2HttpClientHandler httpClientHandler = new HttpClientHandler();
3try (FileStream sslClientCert = new FileStream("C:/path/to/clientcert.p12", FileStream.Mode.READ_ONLY))
4{
5 httpClientHandler.setClientCertificate(sslClientCert, "***insert password***");
6}
7
8// Connect to the Swisscom Signing Service
9try (Session session = new Session(new URI("https://ais.swisscom.com"), httpClientHandler))
10{
11 // Sign a PDF document
12 sign(session, identity, commonName, inPath, outPath);
13}
1private static void sign(Session session, String identity, String commonName, String inPath, String outPath) throws Exception
2{
3 // Create a signing certificate for a static identity
4 // This can be re-used to sign multiple documents
5 SignatureConfiguration signature = session.createSignatureForStaticIdentity(identity, commonName);
6
7 // Embed validation information to enable the long term validation (LTV) of the signature (default)
8 signature.setEmbedValidationInformation(true);
9
10 try (
11 // Open input document
12 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
13 Document inDoc = Document.open(inStr);
14
15 // Create output stream
16 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
17
18 // Sign the input document
19 Document outDoc = new Signer().sign(inDoc, signature, outStr))
20 {
21 }
22}
Sign a PDF and add a visual appearance.
1static void Sign(string certificateFile, string password, string appConfigFile, string inPath, string outPath)
2{
3 // Create a session to the built-in cryptographic provider
4 using var session = new BuiltIn.Provider();
5
6 // Open certificate file
7 using var pfxStr = File.OpenRead(certificateFile);
8
9 // Create signature configuration from PFX (or P12) file
10 BuiltIn.SignatureConfiguration signature = session.CreateSignatureFromCertificate(pfxStr, password);
11
12 // Create appearance from either an XML or a json file
13 using var appStream = File.OpenRead(appConfigFile);
14 if (Path.GetExtension(appConfigFile) == ".xml")
15 signature.Appearance = Appearance.CreateFromXml(appStream);
16 else
17 signature.Appearance = Appearance.CreateFromJson(appStream);
18
19 signature.Appearance.PageNumber = 1;
20 signature.Appearance.CustomTextVariables.Add("company", "Daily Planet");
21
22 // Open input document
23 using var inStr = File.OpenRead(inPath);
24 using var inDoc = Document.Open(inStr);
25
26 // Create stream for output file
27 using var outStr = File.Create(outPath);
28
29 // Sign the input document
30 using var outDoc = new Signer().Sign(inDoc, signature, outStr);
31}
1private static void sign(String certificateFile, String password, String appConfigFile, String inPath, String outPath) throws Exception
2{
3 try (
4 // Create a session to the built-in cryptographic provider
5 Provider session = new Provider();
6
7 // Open certificate file
8 FileStream pfxStr = new FileStream(certificateFile, FileStream.Mode.READ_ONLY))
9 {
10 // Create signature configuration from PFX (or P12) file
11 SignatureConfiguration signature = session.createSignatureFromCertificate(pfxStr, password);
12
13 try (
14 // Create appearance from either an XML or a json file
15 FileStream appConfigStr = new FileStream(appConfigFile, FileStream.Mode.READ_ONLY))
16 {
17 if (appConfigFile.toLowerCase().endsWith(".xml"))
18 signature.setAppearance(Appearance.createFromXml(appConfigStr));
19 else
20 signature.setAppearance(Appearance.createFromJson(appConfigStr));
21
22 signature.getAppearance().setPageNumber(1);
23 signature.getAppearance().getCustomTextVariables().put("company", "Daily Planet");
24
25 try(
26 // Open input document
27 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
28 Document inDoc = Document.open(inStr);
29
30 // Create a stream for the output file
31 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
32
33 // Sign the input document
34 Document outDoc = new Signer().sign(inDoc, signature, outStr))
35 {
36 }
37 }
38 }
39}
Assembling documents
Merge PDFs
1private static void Merge(IEnumerable<string> inPaths, string outPath)
2{
3 // Create output stream
4 using var outStream = File.Create(outPath);
5 using var docAssembler = new PdfTools.DocumentAssembly.DocumentAssembler(outStream);
6
7 foreach (var inPath in inPaths)
8 {
9 using var inStream = File.OpenRead(inPath);
10 using var inDoc = PdfTools.Pdf.Document.Open(inStream);
11 // Append the content of the input documents to the output document
12 docAssembler.Append(inDoc);
13 }
14
15 // Merge input documents into an output document
16 docAssembler.Assemble();
17}
1 private static void merge(String[] inPaths, String outPath) throws Exception
2 {
3 try (
4 // Create output stream
5 FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
6 DocumentAssembler docAssembler = new DocumentAssembler(outStream)) {
7 for (String inPath : inPaths) {
8 try (
9 // Open input document
10 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
11 Document inDoc = Document.open(inStr)) {
12 // Append the content of each input document to the output document
13 docAssembler.append(inDoc);
14 }
15 }
16 // Merge input documents into an output document
17 docAssembler.assemble();
18 }
19 }
Split PDF document
1private static void Split(string inPath, string outPathPrefix)
2{
3 // Open input document
4 using var inStream = File.OpenRead(inPath);
5 using var inDoc = PdfTools.Pdf.Document.Open(inStream);
6
7 // Split the input document page by page
8 for (int i = 1; i <= inDoc.PageCount; ++i)
9 {
10 using var outStream = File.Create(outPathPrefix + i + ".pdf");
11 using var docAssembler = new PdfTools.DocumentAssembly.DocumentAssembler(outStream);
12 docAssembler.Append(inDoc, i, i);
13 docAssembler.Assemble();
14 }
15}
1private static void split(String inPath, String outPathPrefix) throws Exception
2{
3 try (
4 // Open input document
5 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
6 Document inDoc = Document.open(inStr)) {
7 for (int i = 1; i <= inDoc.getPageCount(); ++i) {
8 try (
9 // Create output stream for each page of the input document
10 FileStream outStream = new FileStream(outPathPrefix + i + ".pdf", FileStream.Mode.READ_WRITE_NEW);
11 DocumentAssembler docAssembler = new DocumentAssembler(outStream)) {
12 docAssembler.append(inDoc, i, i);
13 docAssembler.assemble();
14 }
15 }
16 }
17}
Encrypt documents
Decrypt an encrypted PDF
1static void Decrypt(string password, string inPath, string outPath)
2{
3 // Use password to open encrypted input document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr, password);
6
7 if (inDoc.Permissions == null)
8 throw new Exception("Input file is not encrypted.");
9
10 // Create stream for output file
11 using var outStr = File.Create(outPath);
12
13 // Set encryption options
14 var outputOptions = new Sign.OutputOptions()
15 {
16 // Set encryption parameters to no encryption
17 Encryption = null,
18 // Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
19 // (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
20 RemoveSignatures = Sign.SignatureRemoval.Signed,
21 };
22
23 // Decrypt the document
24 using var outDoc = new Sign.Signer().Process(inDoc, outStr, outputOptions);
25}
1private static void decrypt(String password, String inPath, String outPath) throws Exception
2{
3 try (
4 // Use password to open encrypted input document
5 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
6 Document inDoc = Document.open(inStr, password))
7 {
8 if (inDoc.getPermissions() == null)
9 throw new Exception("Input file is not encrypted.");
10
11 // Set encryption options
12 OutputOptions outputOptions = new OutputOptions();
13
14 // Set encryption parameters to no encryption
15 outputOptions.setEncryption(null);
16
17 // Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
18 // (see warning category WarningCategory.SIGNED_DOC_ENCRYPTION_UNCHANGED).
19 outputOptions.setRemoveSignatures(SignatureRemoval.SIGNED);
20
21 try(
22 // Create output stream
23 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
24
25 // Decrypt the document
26 Document outDoc = new Signer().process(inDoc, outStr, outputOptions))
27 {
28 }
29 }
30}
Encrypted PDF
1static void Encrypt(string password, string inPath, string outPath)
2{
3 // Open input document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create stream for output file
8 using var outStr = File.Create(outPath);
9
10 // Set encryption options
11 var outputOptions = new Sign.OutputOptions()
12 {
13 // Set a user password that will be required to open the document.
14 // Note that this will remove PDF/A conformance of input files (see warning category Sign.WarningCategory.PdfARemoved)
15 Encryption = new Encryption(password, null, Permission.All),
16 // Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
17 // (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
18 RemoveSignatures = Sign.SignatureRemoval.Signed,
19 };
20
21 // Encrypt the document
22 using var outDoc = new Sign.Signer().Process(inDoc, outStr, outputOptions);
23}
1private static void encrypt(String password, String inPath, String outPath) throws Exception
2{
3 try (
4 // Open input document
5 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
6 Document inDoc = Document.open(inStr))
7 {
8 // Set encryption options
9 OutputOptions outputOptions = new OutputOptions();
10
11 // Set a user password that will be required to open the document.
12 // Note that this will remove PDF/A conformance of input files (see warning category WarningCategory.PDF_A_REMOVED)
13 outputOptions.setEncryption(new Encryption(password, null, Permission.ALL));
14
15 // Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
16 // (see warning category WarningCategory.SIGNED_DOC_ENCRYPTION_UNCHANGED).
17 outputOptions.setRemoveSignatures(SignatureRemoval.SIGNED);
18
19 try(
20 // Create output stream
21 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
22
23 // Encrypt the document
24 Document outDoc = new Signer().process(inDoc, outStr, outputOptions))
25 {
26 }
27 }
28}
Converting images to PDF documents
Convert an image to an accessible PDF/A document
1private static void Image2Pdf(string inPath, string alternateText, string outPath)
2{
3 // Open image document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create the profile that defines the conversion parameters.
8 // The Archive profile converts images to PDF/A documents for archiving.
9 var profile = new Profiles.Archive();
10
11 // Set conformance of output document to PDF/A-2a
12 profile.Conformance = new Conformance(2, Conformance.PdfALevel.A);
13
14 // For PDF/A level A, an alternate text is required for each page of the image.
15 // This is optional for other PDF/A levels, e.g. PDF/A-2b.
16 profile.Language = "en";
17 profile.AlternateText.Add(alternateText);
18
19 // Optionally other profile parameters can be changed according to the
20 // requirements of your conversion process.
21
22 // Create output stream
23 using var outStr = File.Create(outPath);
24
25 // Convert the image to a tagged PDF/A document
26 using var outDoc = new Converter().Convert(inDoc, outStr, profile);
27}
1private static void image2Pdf(String inPath, String alternateText, String outPath) throws Exception
2{
3 // Create the profile that defines the conversion parameters.
4 // The Archive profile converts images to PDF/A documents for archiving.
5 Archive profile = new Archive();
6
7 // Set conformance of output document to PDF/A-2a
8 profile.setConformance(new Conformance(new Conformance.PdfAVersion(2, Level.A)));
9
10 // For PDF/A level A, an alternate text is required for each page of the image.
11 // This is optional for other PDF/A levels, e.g. PDF/A-2b.
12 profile.setLanguage("en");
13 profile.getAlternateText().add(alternateText);
14
15 // Optionally other profile parameters can be changed according to the
16 // requirements of your conversion process.
17
18 try (
19 // Open input document
20 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
21 Document inDoc = Document.open(inStr);
22
23 // Create output stream
24 FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
25
26 // Convert the image to a tagged PDF/A document
27 com.pdftools.pdf.Document outDoc = new Converter().convert(inDoc, outStream, profile))
28 {
29 }
30}
Convert image to PDF
1private static void Image2Pdf(string inPath, string outPath)
2{
3 // Open image document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create the profile that defines the conversion parameters.
8 // The Default profile converts images to PDF documents.
9 var profile = new Profiles.Default();
10
11 // Optionally, the profile's parameters can be changed according to the
12 // requirements of your conversion process.
13
14 // Create output stream
15 using var outStr = File.Create(outPath);
16
17 // Convert the image to a PDF document
18 using var outDoc = new Converter().Convert(inDoc, outStr, profile);
19}
1private static void image2Pdf(String inPath, String outPath) throws Exception
2{
3 // Create the profile that defines the conversion parameters.
4 // The Default profile converts images to PDF documents.
5 Default profile = new Default();
6
7 // Optionally, the profile's parameters can be changed according to the
8 // requirements of your conversion process.
9
10 try (
11 // Open input document
12 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
13 Document inDoc = Document.open(inStr);
14
15 // Create output stream
16 FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
17
18 // Convert the image to a PDF document
19 com.pdftools.pdf.Document outDoc = new Converter().convert(inDoc, outStream, profile))
20 {
21 }
22}
Convert multiple images to a PDF
1private static void Images2Pdf(IEnumerable<string> inPaths, string outPath)
2{
3 var streams = new List<FileStream>();
4 var images = new DocumentList();
5 try
6 {
7 // Open input images and store in list
8 foreach (var inPath in inPaths)
9 {
10 var stream = File.OpenRead(inPath);
11 streams.Add(stream);
12 images.Add(Document.Open(stream));
13 }
14
15 // Create the profile that defines the conversion parameters.
16 var profile = new Profiles.Default();
17
18 // Optionally the profile's parameters can be changed according to the
19 // requirements of your conversion process.
20 // Create output stream
21 using var outStream = File.Create(outPath);
22 using var outPdf = new Converter().ConvertMultiple(images, outStream, profile);
23 }
24 finally
25 {
26 foreach (var image in images)
27 image.Dispose();
28 foreach (var stream in streams)
29 stream.Dispose();
30 }
31}
Optimizing documents
Optimize a PDF
1private static void Optimize(string inPath, string outPath)
2{
3 // Open input document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create the profile that defines the optimization parameters.
8 // The Web profile is used to optimize documents for electronic document exchange.
9 var profile = new Profiles.Web();
10
11 // Optionally the profile's parameters can be changed according to the
12 // requirements of your optimization process.
13
14 // Create output stream
15 using var outStr = File.Create(outPath);
16
17 // Optimize the document
18 using var outDoc = new Optimizer().OptimizeDocument(inDoc, outStr, profile);
19}
1private static void optimize(String inPath, String outPath) throws Exception
2{
3 // Create the profile that defines the optimization parameters.
4 // The Web profile is used to optimize documents for electronic document exchange.
5 Web profile = new Web();
6
7 // Optionally the profile's parameters can be changed according to the
8 // requirements of your optimization process.
9
10 try (
11 // Open input document
12 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
13 Document inDoc = Document.open(inStr);
14
15 // Create output stream
16 FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
17
18 // Optimize the document
19 Document outDoc = new Optimizer().optimizeDocument(inDoc, outStr, profile))
20 {
21 }
22}
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
4TPdfToolsSys_StreamDescriptor inDesc;
5PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
6pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
7GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
8 pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
9 szErrorBuff, PdfTools_GetLastError());
10
11// Create output stream for writing
12pOutStream = _tfopen(szOutPath, _T("wb+"));
13GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
14TPdfToolsSys_StreamDescriptor outDesc;
15PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);
16
17// Create the profile that defines the optimization parameters.
18// The Web profile is suitable to optimize documents for electronic document exchange.
19pProfile = (TPdfToolsOptimizationProfiles_Profile*)PdfToolsOptimizationProfiles_Web_New();
20
21// Optionally the profile's parameters can be changed according to the
22// requirements of your optimization process.
23
24// Optimize the document
25pOptimizer = PdfToolsOptimization_Optimizer_New();
26pOutDoc = PdfToolsOptimization_Optimizer_OptimizeDocument(pOptimizer, pInDoc, &outDesc, pProfile, NULL);
27GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
28 PdfTools_GetLastError());
29
Convert a PDF document to PDF/A-2b if necessary
1static void ConvertIfNotConforming(string inPath, string outPath, Conformance conformance)
2{
3 // Open input document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create the Validator object, and use the Conformance object to create
8 // an AnalysisOptions object that controls the behavior of the Validator.
9 var validator = new Validator();
10 var analysisOptions = new AnalysisOptions() { Conformance = conformance };
11
12 // Run the analysis, and check the results.
13 // Only proceed if document is not conforming.
14 var analysisResult = validator.Analyze(inDoc, analysisOptions);
15 if (analysisResult.IsConforming)
16 {
17 Console.WriteLine($"Document conforms to {inDoc.Conformance} already.");
18 return;
19 }
20
21 // Create a converter object
22 var converter = new Converter();
23
24 // Add handler for conversion events
25 var eventsSeverity = EventSeverity.Information;
26 converter.ConversionEvent += (s, e) =>
27 {
28 // Get the event's suggested severity
29 var severity = e.Severity;
30
31 // Optionally the suggested severity can be changed according to
32 // the requirements of your conversion process and, for example,
33 // the event's category (e.Category).
34
35 if (severity > eventsSeverity)
36 eventsSeverity = severity;
37
38 // Report conversion event
39 Console.WriteLine("- {0} {1}: {2} ({3}{4})",
40 severity.ToString()[0], e.Category, e.Message, e.Context, e.PageNo > 0 ? " page " + e.PageNo : ""
41 );
42 };
43
44 // Create stream for output file
45 using var outStr = File.Create(outPath);
46
47 // Convert the input document to PDF/A using the converter object
48 // and its conversion event handler
49 using var outDoc = converter.Convert(analysisResult, inDoc, outStr);
50
51 // Check if critical conversion events occurred
52 switch (eventsSeverity)
53 {
54 case EventSeverity.Information:
55 Console.WriteLine($"Successfully converted document to {outDoc.Conformance}.");
56 break;
57
58 case EventSeverity.Warning:
59 Console.WriteLine($"Warnings occurred during the conversion of document to {outDoc.Conformance}.");
60 Console.WriteLine($"Check the output file to decide if the result is acceptable.");
61 break;
62
63 case EventSeverity.Error:
64 throw new Exception($"Unable to convert document to {conformance} because of critical conversion events.");
65 }
66}
1private static void convertIfNotConforming(String inPath, String outPath, Conformance conformance) throws Exception
2{
3 // Open input document
4 try (FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
5 Document inDoc = Document.open(inStr))
6 {
7 // Create the Validator object, and use the Conformance object to create
8 // an AnalysisOptions object that controls the behavior of the Validator.
9 Validator validator = new Validator();
10 AnalysisOptions analysisOptions = new AnalysisOptions();
11 analysisOptions.setConformance(conformance);
12
13 // Run the analysis, and check the results.
14 // Only proceed if document is not conforming.
15 AnalysisResult analysisResult = validator.analyze(inDoc, analysisOptions);
16 if (analysisResult.getIsConforming())
17 {
18 System.out.println("Document conforms to " + inDoc.getConformance() + " already.");
19 return;
20 }
21
22 // Create output stream
23 try (FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW))
24 {
25 // Create a converter object
26 Converter converter = new Converter();
27
28 // Add handler for conversion events
29 class EventListener implements ConversionEventListener
30 {
31 private EventSeverity eventsSeverity = EventSeverity.INFORMATION;
32
33 public EventSeverity getEventsSeverity() {
34 return eventsSeverity;
35 }
36
37 @Override
38 public void conversionEvent(ConversionEvent event) {
39 // Get the event's suggested severity
40 EventSeverity severity = event.getSeverity();
41
42 // Optionally the suggested severity can be changed according to
43 // the requirements of your conversion process and, for example,
44 // the event's category (e.Category).
45
46 if (severity.ordinal() > eventsSeverity.ordinal())
47 eventsSeverity = severity;
48
49 // Report conversion event
50 System.out.format("- %c %s: %s (%s%s)%n", severity.toString().charAt(0), event.getCategory(), event.getMessage(), event.getContext(), event.getPageNo() > 0 ? " on page " + event.getPageNo() : "");
51 }
52 }
53 EventListener el = new EventListener();
54
55 converter.addConversionEventListener(el);
56
57 // Convert the input document to PDF/A using the converter object
58 // and its conversion event handler
59 try (Document outDoc = converter.convert(analysisResult, inDoc, outStr))
60 {
61 // Check if critical conversion events occurred
62 switch (el.getEventsSeverity())
63 {
64 case INFORMATION:
65 System.out.println("Successfully converted document to " + outDoc.getConformance() + ".");
66 break;
67
68 case WARNING:
69 System.out.println("Warnings occurred during the conversion of document to " + outDoc.getConformance() + ".");
70 System.out.println("Check the output file to decide if the result is acceptable.");
71 break;
72
73 case ERROR:
74 throw new Exception("Unable to convert document to " + conformance + " because of critical conversion events.");
75 }
76 }
77 }
78
79 }
80}
1void EventListener(void* pContext, const char* szDataPart, const char* szMessage,
2 TPdfToolsPdfAConversion_EventSeverity iSeverity, TPdfToolsPdfAConversion_EventCategory iCategory,
3 TPdfToolsPdfAConversion_EventCode iCode, const char* szContext, int iPageNo)
4{
5 // iSeverity is the event's suggested severity
6 // Optionally the suggested severity can be changed according to
7 // the requirements of your conversion process and, for example,
8 // the event's category (e.Category).
9
10 if (iSeverity > iEventsSeverity)
11 iEventsSeverity = iSeverity;
12
13 // Report conversion event
14 TCHAR cSeverity = iSeverity == ePdfToolsPdfAConversion_EventSeverity_Information ? 'I'
15 : ePdfToolsPdfAConversion_EventSeverity_Warning ? 'W'
16 : 'E';
17 if (iPageNo > 0)
18 _tprintf(_T("- %c %d: %s (%s on page %d)\n"), cSeverity, iCategory, szMessage, szContext, iPageNo);
19 else
20 _tprintf(_T("- %c %d: %s (%s)\n"), cSeverity, iCategory, szMessage, szContext);
21}
1void ConvertIfNotConforming(const TCHAR* szInPath, const TCHAR* szOutPath, TPdfToolsPdf_Conformance iConf)
2{
3 TPdfToolsPdfAValidation_AnalysisOptions* pAOpt = NULL;
4 TPdfToolsPdfAValidation_Validator* pValidator = NULL;
5 TPdfToolsPdfAValidation_AnalysisResult* pARes = NULL;
6 TPdfToolsPdfAConversion_ConversionOptions* pConvOpt = NULL;
7 TPdfToolsPdfAConversion_Converter* pConv = NULL;
8 TPdfToolsPdf_Document* pOutDoc = NULL;
9 TPdfToolsPdf_Document* pInDoc = NULL;
10 FILE* pInStream = NULL;
11 FILE* pOutStream = NULL;
12
13 // Open input document
14 pInStream = _tfopen(szInPath, _T("rb"));
15 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
16 TPdfToolsSys_StreamDescriptor inDesc;
17 PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
18 pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
19 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Failed to open document \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
20 szErrBuf, PdfTools_GetLastError());
21
22 // Create validator to analyze PDF/A standard conformance of input document
23 pAOpt = PdfToolsPdfAValidation_AnalysisOptions_New();
24 PdfToolsPdfAValidation_AnalysisOptions_SetConformance(pAOpt, iConf);
25 pValidator = PdfToolsPdfAValidation_Validator_New();
26 pARes = PdfToolsPdfAValidation_Validator_Analyze(pValidator, pInDoc, pAOpt);
27 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pARes, _T("Failed to analyze document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
28 PdfTools_GetLastError());
29
30 // Check if conversion to PDF/A is necessary
31 if (PdfToolsPdfAValidation_AnalysisResult_IsConforming(pARes))
32 {
33 printf("Document conforms to %s already.\n", PdfToolsPdf_Conformance_ToStringA(iConf));
34 goto cleanup;
35 }
36
37 // Create output stream for writing
38 pOutStream = _tfopen(szOutPath, _T("wb+"));
39 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to create the output file \"%s\".\n"), szOutPath);
40 TPdfToolsSys_StreamDescriptor outDesc;
41 PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);
42
43 // Convert the input document to PDF/A using the converter object
44 // and its conversion event handler
45 pConvOpt = PdfToolsPdfAConversion_ConversionOptions_New();
46 pConv = PdfToolsPdfAConversion_Converter_New();
47 PdfToolsPdfAConversion_Converter_AddConversionEventHandlerA(
48 pConv, NULL, (TPdfToolsPdfAConversion_Converter_ConversionEventA)EventListener);
49 pOutDoc = PdfToolsPdfAConversion_Converter_Convert(pConv, pARes, pInDoc, &outDesc, pConvOpt, NULL);
50 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Failed to convert document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
51 PdfTools_GetLastError());
52
53 // Check if critical conversion events occurred
54 switch (iEventsSeverity)
55 {
56 case ePdfToolsPdfAConversion_EventSeverity_Information:
57 {
58 TPdfToolsPdf_Conformance iOutConf;
59 PdfToolsPdf_Document_GetConformance(pOutDoc, &iOutConf);
60 printf("Successfully converted document to %s.\n", PdfToolsPdf_Conformance_ToStringA(iOutConf));
61 break;
62 }
63
64 case ePdfToolsPdfAConversion_EventSeverity_Warning:
65 {
66 TPdfToolsPdf_Conformance iOutConf;
67 PdfToolsPdf_Document_GetConformance(pOutDoc, &iOutConf);
68 printf("Warnings occurred during the conversion of document to %s.\n",
69 PdfToolsPdf_Conformance_ToStringA(iOutConf));
70 printf("Check the output file to decide if the result is acceptable.\n");
71 break;
72 }
73
74 case ePdfToolsPdfAConversion_EventSeverity_Error:
75 {
76 printf("Unable to convert document to %s because of critical conversion events.\n",
77 PdfToolsPdf_Conformance_ToStringA(iConf));
78 break;
79 }
80 }
81
82cleanup:
83 PdfToolsPdf_Document_Close(pOutDoc);
84 PdfTools_Release(pConv);
85 PdfTools_Release(pConvOpt);
86 PdfTools_Release(pARes);
87 PdfTools_Release(pValidator);
88 PdfTools_Release(pAOpt);
89 PdfToolsPdf_Document_Close(pInDoc);
90 if (pInStream)
91 fclose(pInStream);
92 if (pOutStream)
93 fclose(pOutStream);
94}
Converting documents to rasterized images
Convert PDF to image
1private static void Pdf2Image(string inPath, string outPath)
2{
3 // Open input document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create the profile that defines the conversion parameters.
8 // The Archive profile converts PDF documents to TIFF images for archiving.
9 var profile = new Profiles.Archive();
10
11 // Optionally the profile's parameters can be changed according to the
12 // requirements of your conversion process.
13
14 // Create output stream
15 using var outStr = File.Create(outPath);
16
17 // Convert the PDF document to an image document
18 using var outDoc = new Converter().ConvertDocument(inDoc, outStr, profile);
19}
1private static void pdf2Image(String inPath, String outPath) throws Exception
2{
3 // Create the profile that defines the conversion parameters.
4 // The Archive profile converts PDF documents to TIFF images for archiving.
5 Archive profile = new Archive();
6
7 // Optionally the profile's parameters can be changed according to the
8 // requirements of your conversion process.
9
10 try (
11 // Open input document
12 FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
13 Document inDoc = Document.open(inStr);
14
15 // Create output stream
16 FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
17
18 // Convert the PDF document to an image document
19 com.pdftools.image.Document outDoc = new Converter().convertDocument(inDoc, outStream, profile))
20 {
21 }
22}
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
4TPdfToolsSys_StreamDescriptor inDesc;
5PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
6pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
7GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
8 pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
9 szErrorBuff, PdfTools_GetLastError());
10
11// Create output stream for writing
12pOutStream = _tfopen(szOutPath, _T("wb+"));
13GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the output file \"%s\" for writing.\n"), szOutPath);
14TPdfToolsSys_StreamDescriptor outDesc;
15PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);
16
17// Create the profile that defines the conversion parameters.
18// The Archive profile converts PDF documents to TIFF images for archiving.
19pProfile = (TPdfToolsPdf2ImageProfiles_Profile*)PdfToolsPdf2ImageProfiles_Archive_New();
20
21// Optionally the profile's parameters can be changed according to the
22// requirements of your conversion process.
23
24// Convert the PDF document to an image document
25pConverter = PdfToolsPdf2Image_Converter_New();
26pOutDoc =
27 (TPdfToolsImage_Document*)PdfToolsPdf2Image_Converter_ConvertDocument(pConverter, pInDoc, &outDesc, pProfile);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
29 PdfTools_GetLastError());
30
Validate the conformance of documents
Validate the PDF conformance
1private static ValidationResult Validate(string inPath)
2{
3 // Open the document
4 using var inStr = File.OpenRead(inPath);
5 using var inDoc = Document.Open(inStr);
6
7 // Create a validator object that writes all validation error messages to the console
8 var validator = new Validator();
9 validator.Error += (s, e) => Console.WriteLine("- {0}: {1} ({2}{3})", e.Category, e.Message, e.Context, e.PageNo > 0 ? " on page" + e.PageNo : "");
10
11 // Validate the standard conformance of the document
12 return validator.Validate(inDoc);
13}
1private static ValidationResult validate(String inPath) throws Exception
2{
3 // Open input document
4 try (FileStream inStr = new FileStream(inPath, FileStream.Mode.READ_ONLY);
5 Document inDoc = Document.open(inStr))
6 {
7 // Create a validator object that writes all validation error messages to the console
8 Validator validator = new Validator();
9 validator.addErrorListener(
10 (Validator.Error error) ->
11 System.out.format("- %s: %s (%s%s)%n", error.getCategory(), error.getMessage(), error.getContext(), error.getPageNo() > 0 ? String.format(" on page %d", error.getPageNo()) : "")
12 );
13
14 // Validate the standard conformance of the document
15 return validator.validate(inDoc);
16 }
17}
1void ErrorListener(void* pContext, const TCHAR* szDataPart, const TCHAR* szMessage,
2 TPdfToolsPdfAValidation_ErrorCategory iCategory, const TCHAR* szContext, int iPageNo, int iObjectNo)
3{
4 if (iPageNo > 0)
5 _tprintf(_T("- %d: %s (%s on page %d)\n"), iCategory, szMessage, szContext, iPageNo);
6 else
7 _tprintf(_T("- %d: %s (%s)\n"), iCategory, szMessage, szContext);
8}
1void Validate(const TCHAR* szInPath)
2{
3 TPdfToolsPdf_Document* pInDoc = NULL;
4 TPdfToolsPdfAValidation_Validator* pValidator = NULL;
5 TPdfToolsPdfAValidation_ValidationResult* pResult = NULL;
6
7 // Open input document
8 FILE* pInStream = _tfopen(szInPath, _T("rb"));
9 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"), szInPath);
10 TPdfToolsSys_StreamDescriptor inDesc;
11 PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
12 pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
13 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Failed to open document \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
14 szErrBuf, PdfTools_GetLastError());
15
16 // Create a validator object that writes all validation error messages to the console
17 pValidator = PdfToolsPdfAValidation_Validator_New();
18 PdfToolsPdfAValidation_Validator_AddErrorHandler(pValidator, NULL,
19 (TPdfToolsPdfAValidation_Validator_Error)ErrorListener);
20
21 // Validate the standard conformance of the document
22 pResult = PdfToolsPdfAValidation_Validator_Validate(pValidator, pInDoc, NULL);
23 GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pResult, _T("Failed to validate document. %s (ErrorCode: 0x%08x).\n"), szErrBuf,
24 PdfTools_GetLastError());
25
26 // Report validation result
27 TPdfToolsPdf_Conformance iClaimedConformance;
28 PdfToolsPdf_Document_GetConformance(pInDoc, &iClaimedConformance);