Skip to main content
Version: 1.2

Code samples

Here you'll find some samples to get you started with the Pdftools SDK.

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}
Download code sample
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    }
Download code sample
1// Create output stream
2pOutStream = _tfopen(szOutPath, _T("wb+"));
3GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to create output file \"%s\" for writing.\n"), szOutPath);
4TPdfToolsSys_StreamDescriptor outDesc;
5PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);
6pAssembler = PdfToolsDocumentAssembly_DocumentAssembler_New(&outDesc, NULL, NULL);
7
8for (int i = 1; i < argc - 1; i++)
9{
10    szInPath = argv[i];
11    // Open input document
12    pInStream = _tfopen(szInPath, _T("rb"));
13    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInStream, _T("Failed to open the input file \"%s\" for reading.\n"),
14                                     szInPath);
15    TPdfToolsSys_StreamDescriptor inDesc;
16    PdfToolsSysCreateFILEStreamDescriptor(&inDesc, pInStream, 0);
17    pInDoc = PdfToolsPdf_Document_Open(&inDesc, _T(""));
18    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
19        pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
20        szErrorBuff, PdfTools_GetLastError());
21
22    // Append the content of the input documents to the output document
23    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
24        PdfToolsDocumentAssembly_DocumentAssembler_Append(pAssembler, pInDoc, NULL, NULL, NULL, NULL),
25        _T("Failed to append a page. (ErrorCode: 0x%08x).\n"), PdfTools_GetLastError());
26
27    PdfToolsPdf_Document_Close(pInDoc);
28    fclose(pInStream);
29    pInDoc    = NULL;
30    pInStream = NULL;
31}
32// Merge input documents into an output document
33pOutDoc = PdfToolsDocumentAssembly_DocumentAssembler_Assemble(pAssembler);
34
35GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
36                                 PdfTools_GetLastError());
37
Download code sample
1# Create output stream for writing
2with io.FileIO(output_file_path, 'wb+') as output_stream:
3    output_stream_descriptor = StreamDescriptor(output_stream)
4    output_options = pdf_outputoptions_new()
5    assembler = documentassembly_documentassembler_new(output_stream_descriptor, output_options, None)
6    for i in range(0, len(input_files)):
7        # Open input document
8        with io.FileIO(input_files[i], 'rb') as input_file:
9            input_stream_descriptor = StreamDescriptor(input_file)
10            input_document = pdf_document_open(input_stream_descriptor, None)
11            if not input_document:
12                print_error_message("Failed to open input document.")
13                exit(1)
14
15            # Append the content of the input documents to the output document
16            documentassembly_documentassembler_append(assembler, input_document, None, None, None, None)
17
18    # Merge input documents into an output document
19    out_doc = documentassembly_documentassembler_assemble(assembler)
20    if not out_doc:
21        print_error_message("Error while merging PDFs.")
22        exit(1)
23
24    documentassembly_documentassembler_close(assembler)
25    pdf_document_close(out_doc)
26
Download code sample

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 + "_page_" + i + ".pdf");
11        using var docAssembler = new PdfTools.DocumentAssembly.DocumentAssembler(outStream);
12        docAssembler.Append(inDoc, i, i);
13        docAssembler.Assemble();
14    }
15}
Download code sample
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 + "_page_" + 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}
Download code sample
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(""));
7
8GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
9    pInDoc, _T("Failed to create a document from the input file \"%s\". %s (ErrorCode: 0x%08x).\n"), szInPath,
10    szErrorBuff, PdfTools_GetLastError());
11
12// Split input document by generating one output document per page
13int   nPageCount = PdfToolsPdf_Document_GetPageCount(pInDoc);
14TCHAR szPageFileName[256];
15for (int i = 1; i <= nPageCount; i++)
16{
17    CreateOutputFileName(szPageFileName, szOutPath, i);
18
19    // Create output stream for each page of the input document
20    pOutStream = _tfopen(szPageFileName, _T("wb+"));
21    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutStream, _T("Failed to open the input file \"%s\" for reading.\n"),
22                                     szPageFileName);
23    TPdfToolsSys_StreamDescriptor outDesc;
24    PdfToolsSysCreateFILEStreamDescriptor(&outDesc, pOutStream, 0);
25
26    // Split pdf into pages
27    pAssembler = PdfToolsDocumentAssembly_DocumentAssembler_New(&outDesc, NULL, NULL);
28    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
29        PdfToolsDocumentAssembly_DocumentAssembler_Append(pAssembler, pInDoc, &i, &i, NULL, NULL),
30        _T("Failed to append a page. (ErrorCode: 0x%08x).\n"), PdfTools_GetLastError());
31    pOutDoc = PdfToolsDocumentAssembly_DocumentAssembler_Assemble(pAssembler);
32    PdfToolsDocumentAssembly_DocumentAssembler_Close(pAssembler);
33
34    if (pOutDoc)
35        PdfToolsPdf_Document_Close(pOutDoc);
36    if (pOutStream)
37        fclose(pOutStream);
38    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
39                                     PdfTools_GetLastError());
40}
41
Download code sample
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_stream_descriptor, None)
5    if not input_document:
6        print_error_message("Failed to open input document.")
7        exit(1)
8
9    # Split file generating one PDF per page
10    page_count = pdf_document_getpagecount(input_document)            
11    output_options = pdf_outputoptions_new()
12    for i in range(1, page_count + 1):
13        current_out_file = construct_file_name(output_file_path, i)
14        # Create output stream for each page of the input document
15        with io.FileIO(current_out_file, 'wb+') as output_file:
16            output_stream_descriptor = StreamDescriptor(output_file)
17
18            # Split PDF into single page
19            assembler = documentassembly_documentassembler_new(output_stream_descriptor, output_options, None)
20            documentassembly_documentassembler_append(assembler, input_document, i, i, None, None)
21            out_doc = documentassembly_documentassembler_assemble(assembler)
22            if not out_doc:
23                print_error_message("Error while splitting document.")
24                exit(1)  
25
26            documentassembly_documentassembler_close(assembler)
27            pdf_document_close(out_doc)
28
29        print(f"Successfully splitted page {i} and created file {current_out_file}.")
30    pdf_document_close(input_document)
31
Download code sample

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}
Download code sample
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}
Download code sample
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
Download code sample
1# Open input document
2with io.FileIO(input_pdf_path, 'rb') as input_stream:
3    input_stream_descriptor = StreamDescriptor(input_stream)
4    input_document = pdf_document_open(input_stream_descriptor, None)
5    if not input_document:
6        print_error_message(f"Failed to create a document from the input PDF {input_pdf_path}.")
7        exit(1)
8
9    # Create output stream for writing
10    with io.FileIO(output_image_path, 'wb+') as output_stream:
11        output_stream_descriptor = StreamDescriptor(output_stream)
12
13        # Create the profile that defines the conversion parameters.
14        # The Archive profile converts PDF documents to TIFF images for archiving.
15        profile = pdf2imageprofiles_archive_new()
16
17        # Optionally the profile's parameters can be changed according to the
18        # requirements of your conversion process.
19
20        # Convert the PDF document to an image document
21        converter = pdf2image_converter_new()
22        out_image = pdf2image_converter_convertdocument(converter, input_document, output_stream_descriptor, profile)
23        if not out_image:
24            print_error_message(f"Converting PDF to image has failed.")
25            exit(1)
26
27        image_document_close(out_image)
28    pdf_document_close(input_document)
29
Download code sample

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}
Download code sample
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}
Download code sample
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_image = image_document_open(input_stream_descriptor)
5    if not input_image:
6        print_error_message(f"Failed to open input image {input_file_path}.")
7        exit(1)
8
9    # Create output stream for writing
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_stream_descriptor = StreamDescriptor(output_file)
12
13        # Create the profile that defines the conversion parameters.
14        # The Archive profile converts images to PDF/A documents for archiving.
15        profile = image2pdfprofiles_archive_new()
16
17        # Set conformance of output document to PDF/A-2a
18        image2pdfprofiles_archive_setconformance(profile, PdfConformance.PDF_A2_A.value)
19
20        # For PDF/A level A, an alternate text is required for each page of the image.
21        # This is optional for other PDF/A levels, e.g. PDF/A-2b.
22        image2pdfprofiles_archive_setlanguage(profile, "en")
23        alternate_text_list = image2pdfprofiles_archive_getalternatetext(profile)
24        stringlist_add(alternate_text_list, alternate_text)
25
26        # Optionally other profile parameters can be changed according to the 
27        # requirements of your conversion process.
28
29        converter = image2pdf_converter_new()
30        out_document = image2pdf_converter_convert(converter, input_image, output_stream_descriptor, profile, None)
31        if not out_document:
32            print_error_message(f"Error while converting {input_file_path}.")
33            exit(1)
34
35        pdf_document_close(out_document)
36    image_document_close(input_image)
37
38
Download code sample

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}
Download code sample
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}
Download code sample
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 = PdfToolsImage_Document_Open(&inDesc);
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 Default profile converts images to PDF documents.
19pProfile = (TPdfToolsImage2PdfProfiles_Profile*)PdfToolsImage2PdfProfiles_Default_New();
20
21// Convert the image to a PDF document
22pConverter = PdfToolsImage2Pdf_Converter_New();
23pOutDoc = (TPdfToolsPdf_Document*)PdfToolsImage2Pdf_Converter_Convert(pConverter, pInDoc, &outDesc, pProfile, NULL);
24GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
25                                 PdfTools_GetLastError());
26
Download code sample

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}
Download code sample
1private static void Images2Pdf(String[] inPaths, String outPath) throws Exception
2{
3    // Create the profile that defines the conversion parameters.
4    Default profile = new Default();
5
6    List<FileStream> streams = new ArrayList<>();
7    DocumentList images = new DocumentList();
8
9    // Optionally the profile's parameters can be changed according to the 
10    // requirements of your conversion process.
11    try {
12        // Open input documents
13        for (String inPath : inPaths) {
14            FileStream stream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
15            streams.add(stream);
16            images.add(Document.open(stream));
17        }
18
19        try (
20            // Create output stream
21            FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
22            // Convert the image to a PDF document
23            com.pdftools.pdf.Document outDoc = new Converter().convertMultiple(images, outStream, profile)) {
24            }
25    }
26    finally {
27        for (Document image : images) 
28            image.close();
29        for (FileStream stream : streams)
30            stream.close();
31    }
32}
Download code sample
1 # Loop over all the image paths and store opened images into list
2 stream_list = []
3 images = image_documentlist_new()
4 for image_path in input_image_paths:
5     input_file = open(image_path, 'rb')
6     input_stream_descriptor = StreamDescriptor(input_file)
7     stream_list.append(input_stream_descriptor)
8     input_image = image_document_open(input_stream_descriptor)
9     if not input_image:
10         print_error_message(f"Failed to open input image {image_path}.")
11         exit(1)                
12     image_documentlist_add(images, input_image)
13
14# Create output stream for writing
15 with io.FileIO(output_file_path, 'wb+') as output_file:
16     output_stream_descriptor = StreamDescriptor(output_file)
17
18     # Create the profile that defines the conversion parameters.
19     profile = image2pdfprofiles_default_new()
20
21     converter = image2pdf_converter_new()
22
23     # Create output PDF
24     out_document = image2pdf_converter_convertmultiple(converter, images, output_stream_descriptor, profile, None)
25     if not out_document:
26         print_error_message(f"Error while converting images to Pdf.")
27         exit(1)
28
29     pdf_document_close(out_document)
30
Download code sample

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}
Download code sample
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}
Download code sample
1// Use password to open encrypted 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, szPassword);
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// Check if input file is encrypted
18BOOL bIsGetPermissionsSuccessful = PdfToolsPdf_Document_GetPermissions(pInDoc, &iPermissions);
19if (!bIsGetPermissionsSuccessful)
20{
21    if (PdfTools_GetLastError() == 0)
22    {
23        _tprintf(_T("Validation failed, input file \"%s\" is not encrypted.\n"), szInPath);
24        iRet = 1;
25        goto cleanup;
26    }
27    else
28    {
29        nBufSize = PdfTools_GetLastErrorMessage(NULL, 0);
30        PdfTools_GetLastErrorMessage(szErrorBuff, MIN(ARRAY_SIZE(szErrorBuff), nBufSize));
31        _tprintf(_T("Failed to get permissions for input file \"%s\", error %s \n"), szInPath, szErrorBuff);
32        iRet = 1;
33        goto cleanup;
34    }
35}
36
37// Set encryption options
38pOptions = PdfToolsSign_OutputOptions_New();
39
40// Set encryption parameters to no encryption
41PdfToolsPdf_OutputOptions_SetEncryption((TPdfToolsPdf_OutputOptions*)pOptions, NULL);
42
43// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
44// (see warning category Sign.WarningCategory.SignedDocEncryptionUnchanged).
45PdfToolsSign_OutputOptions_SetRemoveSignatures(pOptions, ePdfToolsSign_SignatureRemoval_Signed);
46
47// Decrypt the document
48pSigner = PdfToolsSign_Signer_New();
49pOutDoc = PdfToolsSign_Signer_Process(pSigner, pInDoc, &outDesc, pOptions, NULL);
50GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
51                                 PdfTools_GetLastError());
52
53
Download code sample
1# Use password to open encrypted input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_stream_descriptor, password)
5    if not input_document:
6        print_error_message("Failed to open input document.")
7        exit(1)
8
9    # Create output stream for writing
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_stream_descriptor = StreamDescriptor(output_file)
12
13        # Check if input file is encrypted
14        permission = c_int(PdfPermission.NONE.value)
15        isGetPermissionSuccessful = pdf_document_getpermissions(input_document, permission)
16        if not isGetPermissionSuccessful:
17            if getlasterror() == ErrorCode.SUCCESS:
18                print(f"Validation failed, input file {input_file_path} is not encrypted.")
19                exit(1)
20            else:
21                print_error_message(f"Failed to get permissions for input file {input_file_path}.")
22                exit(1)
23
24        # Set encryption options
25        options = sign_outputoptions_new()
26
27        # Set encryption parameters to no encryption
28        pdf_outputoptions_setencryption(options, None)
29
30        # Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
31        # (see warning category SignWarningCategory.SIGNED_DOC_ENCRYPTION_UNCHANGED).
32        sign_outputoptions_setremovesignatures(options, SignSignatureRemoval.SIGNED.value)
33
34        # Decrypt the document
35        signer = sign_signer_new()
36        out_document = sign_signer_process(signer, input_document, output_stream_descriptor, options, None)
37        if not out_document:
38            print_error_message("The processing has failed.")
39            exit(1)  
40
41        pdf_document_close(out_document)
42    pdf_document_close(input_document)
43
Download code sample

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}
Download code sample
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}
Download code sample
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// Set encryption options
18pOptions = PdfToolsSign_OutputOptions_New();
19
20// Set a user password that will be required to open the document.
21// Note that this will remove PDF/A conformance of input files (see warning category
22// ePdfToolsSign_WarningCategory_PdfARemoved)
23pEncryption = PdfToolsPdf_Encryption_New(szPassword, NULL, ePdfToolsPdf_Permission_All);
24PdfToolsPdf_OutputOptions_SetEncryption((TPdfToolsPdf_OutputOptions*)pOptions, pEncryption);
25
26// Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
27// (see warning category ePdfToolsSign_WarningCategory_SignedDocEncryptionUnchanged).
28PdfToolsSign_OutputOptions_SetRemoveSignatures(pOptions, ePdfToolsSign_SignatureRemoval_Signed);
29
30// Encrypt the document
31pSigner = PdfToolsSign_Signer_New();
32pOutDoc = PdfToolsSign_Signer_Process(pSigner, pInDoc, &outDesc, pOptions, NULL);
33GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
34                                 PdfTools_GetLastError());
35
36
Download code sample
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_stream_descriptor, password)
5    if not input_document:
6        print_error_message("Failed to open input document.")
7        exit(1)
8
9    # Create output stream for writing
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_stream_descriptor = StreamDescriptor(output_file)
12
13        # Set encryption options
14        options = sign_outputoptions_new()
15
16        # Set a user password that will be required to open the document.
17        # Note that this will remove PDF/A conformance of input files (see warning category
18        # SignWarningCategory.PDF_A_REMOVED)
19        encryption = pdf_encryption_new(password, None, PdfPermission.ALL.value)
20        pdf_outputoptions_setencryption(options, encryption)
21
22        # Allow removal of signatures. Otherwise the Encryption property is ignored for signed input documents
23        # (see warning category SignWarningCategory.SIGNED_DOC_ENCRYPTION_UNCHANGED).
24        sign_outputoptions_setremovesignatures(options, SignSignatureRemoval.SIGNED.value)
25
26        # Encrypt the document
27        signer = sign_signer_new()
28        out_document = sign_signer_process(signer, input_document, output_stream_descriptor, options, None)
29        if not out_document:
30            print_error_message("The processing has failed.")
31            exit(1)  
32
33        pdf_document_close(out_document)
34    pdf_document_close(input_document)
35
Download code sample

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}
Download code sample
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}
Download code sample
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
Download code sample
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_stream_descriptor, None)
5    if not input_document:
6        print_error_message("Failed to open input document.")
7        exit(1)
8
9    # Create output stream for writing
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_stream_descriptor = StreamDescriptor(output_file)
12
13        # Create the profile that defines the optimization parameters.
14        # The Web profile is suitable to optimize documents for electronic document exchange.
15        profile = optimizationprofiles_web_new()
16
17        # Optionally the profile's parameters can be changed according to the
18        # requirements of your optimization process.
19
20        optimizer = optimization_optimizer_new()
21
22        # Optimize the document
23        out_doc = optimization_optimizer_optimizedocument(optimizer, input_document, output_stream_descriptor, profile, None)
24        if not out_doc:
25            print_error_message("Error while optimizing.")
26            exit(1)
27
28        pdf_document_close(out_doc)
29
30    pdf_document_close(input_document)
31
Download code sample

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}
Download code sample
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}
Download code sample
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}
Download code sample
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_stream_descriptor, None)
5    if not input_document:
6        print_error_message(f"Failed to open input document {input_document}.")
7        exit(1)
8
9    # Create validator to analyze PDF/A standard conformance of input document
10    analysis_options = pdfavalidation_analysisoptions_new()
11    conformance = PdfConformance.PDF_A2_B
12    pdfavalidation_analysisoptions_setconformance(analysis_options, conformance.value)
13    validator = pdfavalidation_validator_new()
14    analysis_result = pdfavalidation_validator_analyze(validator, input_document, analysis_options)
15    if not analysis_result:
16        print_error_message(f"Failed to analyze document {input_document}.")
17        exit(1)
18
19    if pdfavalidation_analysisresult_isconforming(analysis_result):
20        print(f"Document {input_file_path} conforms to {conformance.name}.")
21        exit(0)
22
23    # Create output stream for writing
24    with io.FileIO(output_file_path, 'wb+') as output_file:
25        output_stream_descriptor = StreamDescriptor(output_file)
26
27        # Convert the input document to PDF/A using the converter object
28        # and its conversion event handler
29        conversion_options = pdfaconversion_conversionoptions_new()
30        converter = pdfaconversion_converter_new()
31        callback = PdfAConversion_Converter_ConversionEventFunc(event_listener)
32        pdfaconversion_converter_addconversioneventhandler(converter, None, callback)
33        out_document = pdfaconversion_converter_convert(converter, analysis_result, input_document, output_stream_descriptor, conversion_options, None)
34        if not out_document:
35            print_error_message(f"Failed to convert document {input_file_path}.")
36            exit(1)
37
38        # Check if critical conversion events occurred
39        if events_severity == PdfAConversionEventSeverity.INFORMATION:
40            conformance = c_int()
41            pdf_document_getconformance(out_document, conformance)
42            print(f"Successfully converted document {input_file_path} to {PdfConformance(conformance.value).name}.")
43        elif events_severity == PdfAConversionEventSeverity.WARNING:
44            conformance = c_int()
45            pdf_document_getconformance(out_document, conformance)
46            print(f"Warnings occurred during the conversion of document {input_file_path} to {PdfConformance(conformance.value).name}.")
47            print(f"Check the output file {output_file_path} to decide if the result is acceptable.")
48        elif events_severity == PdfAConversionEventSeverity.ERROR:
49            print(f"Unable to convert document {input_file_path} to {PdfConformance(conformance.value).name} because of critical conversion events.")
50
51        pdf_document_close(out_document)
52    pdf_document_close(input_document)
53
1def event_listener(context, data_part, message, severity, category, code, context_info, page_no):
2    # severity is the event's suggested severity
3    # Optionally, the suggested severity can be changed according to
4    # the requirements of your conversion process and, for example,
5    # the event's category.
6
7    global events_severity
8
9    if PdfAConversionEventSeverity(severity) > events_severity:
10        events_severity = PdfAConversionEventSeverity(severity)
11
12    # Report conversion event
13    if severity == PdfAConversionEventSeverity.INFORMATION:
14        severity_char = 'I'
15    elif severity == PdfAConversionEventSeverity.WARNING:
16        severity_char = 'W'
17    else:
18        severity_char = 'E'
19
20    if page_no > 0:
21        print(f"- {severity_char} {PdfAValidationErrorCategory(category).name}: {message.decode()} ({context_info.decode()} on page {page_no})")
22    else:
23        print(f"- {severity_char} {PdfAValidationErrorCategory(category).name}: {message.decode()} ({context_info.decode()})")
24
Download code sample

Powering AI applications

Convert images to an accessible PDF/A document

1// Store stream descriptors and images in lists
2var streams = new List<FileStream>();
3var images = new DocumentList();
4try
5{
6    // Loop over all image paths and store opened images into list
7    foreach (var inPath in imagePaths)
8    {
9        var stream = File.OpenRead(inPath);
10        streams.Add(stream);
11        images.Add(Document.Open(stream));
12    }
13
14    // Create the profile that defines the conversion parameters.
15    // The Archive profile converts images to PDF/A documents for archiving..
16    var profile = new Profiles.Archive();
17
18    // Set conformance of output document to PDF/A-2a
19    profile.Conformance = new Conformance(2, Conformance.PdfALevel.A);
20
21    // For PDF/A level A, an alternate text is required for each page of the image.
22    // This is optional for other PDF/A levels, e.g. PDF/A-2b.
23    profile.Language = "en";
24
25    // Initiate tasks to fetch alternate texts concurrently
26    var altTextTasks = imagePaths.Select(GetAlternateTextAsync).ToArray();
27
28    // Wait for all tasks to complete
29    var altTexts = await Task.WhenAll(altTextTasks);
30
31    // Assign alternate texts to the profile
32    foreach (var altText in altTexts)
33    {
34        profile.AlternateText.Add(altText);
35    }
36
37    // Create output stream
38    using var outStream = File.Create(outputFilePath);
39    using var outPdf = new Converter().ConvertMultiple(images, outStream, profile);
40}
41finally
42{
43    foreach (var image in images)
44        image.Dispose();
45    foreach (var stream in streams)
46        stream.Dispose();
47}
48
1// AI: Create alternate text.
2private static async Task<string> GetAlternateTextAsync(string imagePath)
3{
4    var api = new OpenAI_API.OpenAIAPI("***insert-open-ai-api-key***");
5    var result = await api.Chat.CreateChatCompletionAsync(new ChatRequest()
6    {
7        Model = Model.GPT4_Vision,
8        MaxTokens = 300,
9        Messages = new ChatMessage[]
10        {
11            new ChatMessage(ChatMessageRole.User, "Write a short sentence what can be seen on the image. It shall explain to a person with impaired vision what is on the image. Write the answer in a poetic way in english.", ImageInput.FromFile(imagePath))
12        },
13
14    });
15    return result.ToString();
16}
Download code sample
1
2# Store stream descriptors and images in lists
3stream_list = []
4images = image_documentlist_new()
5
6# Loop over all the image paths and store opened images into list
7for image_path in image_paths:
8    input_file = open(image_path, 'rb')
9    input_stream_descriptor = StreamDescriptor(input_file)
10    stream_list.append(input_stream_descriptor)
11    input_image = image_document_open(input_stream_descriptor)
12    if not input_image:
13        print_error_message(f"Failed to open input image {image_path}.")
14        exit(1)                
15    image_documentlist_add(images, input_image)
16
17# Create output stream for writing
18with io.FileIO(output_file_path, 'wb+') as output_file:
19    output_stream_descriptor = StreamDescriptor(output_file)
20
21    # Create the profile that defines the conversion parameters.
22    # The Archive profile converts images to PDF/A documents for archiving.
23    profile = image2pdfprofiles_archive_new()
24
25    # Set conformance of output document to PDF/A-2a
26    image2pdfprofiles_archive_setconformance(profile, PdfConformance.PDF_A2_A.value)
27
28    # For PDF/A level A, an alternate text is required for each page of the image.
29    # This is optional for other PDF/A levels, e.g. PDF/A-2b.
30    image2pdfprofiles_archive_setlanguage(profile, "en")
31
32    # Set alternate texts created by AI
33    alternate_text_list = image2pdfprofiles_archive_getalternatetext(profile)
34    for image_path in image_paths:                
35        alternate_text = get_alternate_text(image_path)
36        stringlist_add(alternate_text_list, alternate_text)
37
38    converter = image2pdf_converter_new()
39    out_document = image2pdf_converter_convertmultiple(converter, images, output_stream_descriptor, profile, None)
40    if not out_document:
41        print_error_message(f"Error while converting images to Pdf.")
42        exit(1)
43
44    pdf_document_close(out_document)
45
46
1# AI: Create alternate text.
2def get_alternate_text(image_path):
3
4    # Getting base64 representation of input image
5    with open(image_path, "rb") as image_file:
6        base64_image = base64.b64encode(image_file.read()).decode('utf-8')
7
8    # Instantiate OpenAI client and let AI create the alternate text
9    client = OpenAI(api_key="***insert-open-ai-api-key***")
10    response = client.chat.completions.create(
11        model="gpt-4-vision-preview",
12        messages=[
13            {
14            "role": "user",
15            "content": [
16                {"type": "text", "text": "Write a short sentence what can be seen on the image. It shall explain to a person with impaired vision what is on the image. Write the answer in a poetic way in english."},
17                {
18                    "type": "image_url",
19                    "image_url":
20                        {
21                            "url": f"data:image/jpeg;base64,{base64_image}",
22                        },
23                },
24            ],
25            }
26        ],
27        max_tokens=300,
28    )
29
30    return response.choices[0].message.content.strip()
Download code sample

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.CustomTextVariables.Add("company", "Daily Planet");
35
36    // Sign the input document
37    using var outDoc = new Signer().Sign(inDoc, signature, outStr);
38}
Download code sample
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().getCustomTextVariables().put("company", "Daily Planet");
35
36            try(
37                // Create a stream for the output file
38                FileStream outStr = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW);
39
40                // Sign the input document
41                Document outDoc = new Signer().sign(inDoc, signature, outStr))
42            {
43            }
44        }
45    }
46}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample
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 a session to the built-in cryptographic provider
18pSession = PdfToolsCryptoProvidersBuiltIn_Provider_New();
19
20// Create signature configuration from PFX (or P12) file
21pCertificateFileStream = _tfopen(szCertificateFile, _T("rb"));
22GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
23    pCertificateFileStream, _T("Failed to open the certificate file \"%s\" for reading.\n"), szCertificateFile);
24TPdfToolsSys_StreamDescriptor certificateFileDesc;
25PdfToolsSysCreateFILEStreamDescriptor(&certificateFileDesc, pCertificateFileStream, 0);
26pSignatureConfiguration = PdfToolsCryptoProvidersBuiltIn_Provider_CreateSignatureFromCertificate(
27    pSession, &certificateFileDesc, szPassword);
28
29// Embed validation information to enable the long term validation (LTV) of the signature (default)
30PdfToolsCryptoProvidersBuiltIn_SignatureConfiguration_SetValidationInformation(
31    pSignatureConfiguration, ePdfToolsCrypto_ValidationInformation_EmbedInDocument);
32
33// Sign the input document
34pSigner = PdfToolsSign_Signer_New();
35pOutDoc = PdfToolsSign_Signer_Sign(pSigner, pInDoc, pSignatureConfiguration, &outDesc, NULL);
36GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("The processing has failed. (ErrorCode: 0x%08x).\n"),
37                                 PdfTools_GetLastError());
38
Download code sample
1# Open input document
2with io.FileIO(input_pdf_path, 'rb') as input_stream:
3    input_stream_descriptor = StreamDescriptor(input_stream)
4    input_document = pdf_document_open(input_stream_descriptor, None)
5    if not input_document:
6        print_error_message(f"Failed to create a document from the input file {input_pdf_path}.")
7        exit(1)
8
9    # Create output stream for writing
10    with io.FileIO(output_image_path, 'wb+') as output_stream:
11        output_stream_descriptor = StreamDescriptor(output_stream)
12
13        # Create a session to the built-in cryptographic provider
14        session = cryptoprovidersbuiltin_provider_new()
15
16        # Create signature configuration from PFX (or P12) file
17        with io.FileIO(certificate_file, 'rb') as certificate_stream:
18            certificate_stream_descriptor = StreamDescriptor(certificate_stream)
19            signature_configuration = cryptoprovidersbuiltin_provider_createsignaturefromcertificate(session, certificate_stream_descriptor, password)
20            if not signature_configuration:
21                print_error_message(f"Failed to create signature configuration.")
22                exit(1)
23
24            # Embed validation information to enable the long term validation (LTV) of the signature (default)
25            cryptoprovidersbuiltin_signatureconfiguration_setvalidationinformation(signature_configuration, CryptoValidationInformation.EMBED_IN_DOCUMENT.value)
26
27            # Sign the input document
28            signer = sign_signer_new()
29            out_document = sign_signer_sign(signer, input_document, signature_configuration, output_stream_descriptor, None)
30            if not out_document:
31                print_error_message("Failed to sign document.")
32                exit(1)
33
34        pdf_document_close(out_document)
35    pdf_document_close(input_document)
36
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample

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}
Download code sample
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}
Download code sample
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);
29    if (PdfToolsPdfAValidation_ValidationResult_IsConforming(pResult))
30        printf("Document conforms to %s.\n", PdfToolsPdf_Conformance_ToStringA(iClaimedConformance));
31    else
32        printf("Document does not conform to %s.\n", PdfToolsPdf_Conformance_ToStringA(iClaimedConformance));
33
34cleanup:
35    PdfTools_Release(pResult);
36    PdfTools_Release(pValidator);
37    PdfToolsPdf_Document_Close(pInDoc);
38    if (pInStream)
39        fclose(pInStream);
40}
Download code sample
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_stream_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_stream_descriptor, None)
5    if not input_document:
6        print_error_message(f"Failed to open input document {input_file_path}.")
7        exit(1)
8
9    # Create a validator object that writes all validation error messages to the console 
10    validator = pdfavalidation_validator_new()
11    callback = PdfAValidation_Validator_ErrorFunc(error_listener)
12    pdfavalidation_validator_adderrorhandler(validator, None, callback)
13
14    # Validate the standard conformance of the document
15    result = pdfavalidation_validator_validate(validator, input_document, None)
16    if not result:
17        print_error_message("Failed to validate document.")
18        exit(1)
19
20    # Report validation result
21    conformance = c_int()
22    if not pdf_document_getconformance(input_document, conformance):
23        if getlasterror() == ErrorCode.SUCCESS:
24            print("Conformance is unknown.")
25            exit(0)
26        else:
27            print_error_message("Failed to get conformance.")
28            exit(1)
29
30    if pdfavalidation_validationresult_isconforming(result):
31        print(f"Document conforms to {PdfConformance(conformance.value).name}.")
32    else:
33        print(f"Document does not conforms to {PdfConformance(conformance.value).name}.")    
34
35    pdf_document_close(input_document)
36
1def error_listener(context, data_part, message, category, context_text, page_no, object_no):
2    if page_no > 0:
3        print(f"- {PdfAValidationErrorCategory(category).name}: {message.decode()} ({context_text.decode()} on page {page_no})")
4    else:
5        print(f"- {PdfAValidationErrorCategory(category).name}: {message.decode()} ({context_text.decode()})")
Download code sample