L_ReadFileAttachments

include "l_bitmap.h"

L_LTFIL_API L_INT L_ReadFileAttachments(pszFile, ppAttachments, pLoadOptions, pInfo)

Reads the properties of the attachments embedded in the specified file.

Parameters

L_TCHAR *pszFile

Character string containing the name of the owner file that may contain embedded attachments.

L_FILEATTACHMENTS **ppAttachments

Pointer to a variable that will be populated with the properties of any attachments found.

LOADFILEOPTION *pLoadOptions

Pointer to optional extended load options. Pass NULL to use the default load options. Refer to L_LoadFile for more information.

FILEINFO *pInfo

Pointer to a FILEINFO structure. This structure may contain file information used in loading an image, or it may be updated with information about the file being loaded.

This value can be NULL.

Refer to L_LoadFile for more information.

Returns

Value Meaning
SUCCESS The function was successful.
ERROR_NO_ATTACHMENTS The file is a format that supports attachments, such as PDF, but no attachments were found.
ERROR_FEATURE_NOT_SUPPORTED The file is a format that does not support attachments (such as PNG or BMP), or LEADTOOLS does not support reading attachments of this type of format.
ERRORPDFINVALID_PASSWORD The owner file is encrypted. Pass the correct password using L_SetPDFOptions and try again.
< 1 An error occurred. Refer to Return Codes.

Comments

Applications can read the properties of the attachments included in a file by performing the following steps:

  1. Declare a pointer of type L_FILEATTACHMENTS and set its value to NULL.
  2. Call L_ReadFileAttachments on the owner file containing attachments, passing the address of the L_FILEATTACHMENTS pointer.
  3. Process the attachments. An example of processing the attachments would be calling L_ExtractAttachment to extract the attachment's file data.
  4. When the data is no longer needed, call L_FreeAttachments on the pointer to free the memory used by L_FILEATTACHMENTS.

L_ReadFileAttachments returns the following values:

The number of attachment items returned by this method is the same as the FILEINFO.nAttachmentCount value of the object returned by L_FileInfo.

Each L_FILEATTACHMENT contains properties of the attachment such as its pszFileName, uFileLength, and other information provided by the owner document.

Use L_ExtractAttachment to extract the binary content of the attachment file into an output disk file or stream for further processing (for example, by calling L_FileInfo or L_LoadBitmap).

LEADTOOLS supports reading the attachments embedded in the following file format:

PDF

PDF files support embedded attachments of any number and file format (such as PDF, TIFF, XML, etc). PDF files can also be created as a portfolio which contains multiple files assembled into an integrated unit. In these types of documents, the file contains a single generic help page with text such as "For the best experience, open this PDF portfolio in a compatible viewer", as well as any number of attachments and a schema to control how to view the document. The value of FILEINFO.uFlags will contain FILEINFO_PORTFOLIO if the file is a PDF portfolio, and it is up to the application to specify any further handling of the file.

Required DLLs and Libraries

Platforms

Win32, x64, Linux.

See Also

Functions

Example

This example will do the following:

  • Show information on all the attachments embedded in the file
  • Extract the attachment files into an output directory
  • Show the file format and page count of each attachment
    // This example will do the following : 
    // -Show information on all the attachments embedded in the file 
    // - Extract the attachment files into an output directory 
    // - Show the file format and page count of each attachment 
    L_INT ReadFileAttachmentsExample(L_TCHAR* fileName, L_TCHAR* outputDir) 
    { 
       L_INT attachmentCount; 
     
       // Get information on the owner file 
       // This step is optional if we are not interested in determining whether the owner file format 
       // or whether it is a PDF portfolio. 
       FILEINFO fileInfo; 
       L_INT ret = L_FileInfo(fileName, &fileInfo, sizeof(FILEINFO), FILEINFO_TOTALPAGES, NULL); 
       if(ret != SUCCESS) 
          return ret; 
     
       printf("Information\n"); 
       printf("Format:%d\n", fileInfo.Format); 
       // If PDF, check if it is portfolio 
       if(fileInfo.Format == FILE_RAS_PDF) 
          printf("IsPortfolio:%d\n", (fileInfo.Flags & FILEINFO_PORTFOLIO) == FILEINFO_PORTFOLIO); 
       attachmentCount = fileInfo.nAttachmentCount; 
       printf("Attachments:%d\n", fileInfo.nAttachmentCount); 
     
       // Read the properties of the attachments embedded in this file 
       L_FILEATTACHMENTS* attachments = NULL; 
       ret = L_ReadFileAttachments(fileName, &attachments, NULL, NULL); 
       if(ret == ERROR_FEATURE_NOT_SUPPORTED) 
       { 
          // This means the format of the file does not support attachments 
          printf("WARNING: attachments is not supported by this file format\n"); 
          return SUCCESS; 
       } 
       else if(ret == ERROR_NO_ATTACHMENTS) 
       { 
          // This means the format of the file supports attachments but we did not find any in the file 
          printf("WARNING: file has no attachments\n"); 
          return SUCCESS; 
       } 
       else if(ret != SUCCESS) 
       { 
          // Any other error is not expected 
          printf("ERROR: %d\n", ret); 
          return ret; 
       } 
     
       // Sanity check 
       assert(attachments->uItemCount == attachmentCount); 
     
       // Create the output directory if it does not exist 
       CreateDirectory(outputDir, NULL); 
     
       LOADFILEOPTION loadFileOption; 
       L_GetDefaultLoadFileOption(&loadFileOption, sizeof(LOADFILEOPTION)); 
     
       // Extract the attachments 
       for(L_UINT attachmentIndex = 0; attachmentIndex < attachments->uItemCount && ret == SUCCESS; attachmentIndex++) 
       { 
          // Get the current attachment 
          const L_FILEATTACHMENT* attachment = (const L_FILEATTACHMENT*)((const L_UCHAR*)attachments->pItems + (attachments->uItemStructSize * attachmentIndex)); 
     
          // Get the output file name 
          L_TCHAR outputFileName[MAX_PATH] = { 0 }; 
          wcscat(outputFileName, outputDir); 
          size_t len = wcslen(outputFileName); 
          if(outputFileName[len - 1] != '\\') 
             wcscat(outputFileName, L_TEXT("\\")); 
     
          wcscat(outputFileName, attachment->pszFileName); 
          wprintf(L_TEXT("Extracting attachment to output file: %s\n"), outputFileName); 
     
          // Set the attachment number to extract 
          loadFileOption.nAttachment = (L_INT)attachment->uAttachmentNumber; 
     
          // Extract it 
          ret = L_ExtractAttachment(fileName, NULL, 0, &loadFileOption, NULL, 0, outputFileName, NULL, NULL); 
     
          if(ret == SUCCESS) 
          { 
             // Show information on this attachment. Notice that this might fail if the attachment 
             // is not a valid image file format. 
             memset(&fileInfo, 0, sizeof(FILEINFO)); 
             ret = L_FileInfo(outputFileName, &fileInfo, sizeof(FILEINFO), FILEINFO_TOTALPAGES, NULL); 
             if(ret == SUCCESS) 
             { 
                printf(" attachment format is %d and has %d pages\n", fileInfo.Format, fileInfo.TotalPages); 
             } 
             else 
             { 
                printf("  attachment format could not be obtained, error %d\n", ret); 
                ret = SUCCESS; // Swallow this error 
             } 
          } 
       } 
     
       // Free the attachments 
       L_FreeAttachments(attachments); 
     
       return ret; 
    } 
     
    // This sample shows how to load an encrypted attachment contained in an encrypted owner file 
    // The PDF portfolio file (the owner) uses the password 'pass' 
    // The attachment (the embedded file) uses a different password: 'pass1' 
    // The operation requires two passwords, so you will need to use two steps: 
    //    1) Extract the attachment using the owner password (pass) 
    //    2) Load the image from the attachment buffer using the attachment password (pass1) 
    L_INT ReadEncryptedFileAttachmentsExample(L_TCHAR* fileName, pBITMAPHANDLE pBitmap) 
    { 
       LOADFILEOPTION loadFileOption; 
       L_GetDefaultLoadFileOption(&loadFileOption, sizeof(LOADFILEOPTION)); 
       loadFileOption.nAttachment = 1; 
     
       FILEPDFOPTIONS pdfOptions = {sizeof(FILEPDFOPTIONS)}; 
       L_GetPDFOptions(&pdfOptions, sizeof(FILEPDFOPTIONS)); 
       strcpy_s((char *)pdfOptions.szPassword, _countof(pdfOptions.szPassword), "pass1"); // try first the password for the attachment (pass1) 
       L_SetPDFOptions(&pdfOptions); 
     
       // Try to load the image stored in attachment 1 using the password for the owner file - should fail 
       L_INT nRet = L_LoadFile(fileName, pBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, LOADFILE_ALLOCATE | LOADFILE_STORE, NULL, NULL, &loadFileOption, NULL); 
       assert(nRet == ERROR_PDF_INVALID_PASSWORD); 
     
       if(nRet == ERROR_PDF_INVALID_PASSWORD) 
       { 
          strcpy_s((char *)pdfOptions.szPassword, _countof(pdfOptions.szPassword), "pass"); // use the password for the owner file 
          L_SetPDFOptions(&pdfOptions); 
     
          L_UCHAR *pBuffer = NULL; 
          L_SIZE_T uBufferSize = 0; 
     
          // Extract attachment 1 (= loadFileOption.PageNumber) to a memory buffer. 
          // L_ExtractAttachment will allocate the buffer and store its pointer in pBuffer. 
          // The buffer size will be stored in uBufferSize 
          // We will need to free the buffer using L_FreeBuffer when we do not need it anymore. 
          nRet = L_ExtractAttachment(fileName, NULL, NULL, &loadFileOption, NULL, 0, NULL, &pBuffer, &uBufferSize); 
          if(nRet != SUCCESS) 
             return nRet; 
     
          // Try loading the attachment without submitting the correct password. This operation should fail 
          nRet = L_LoadMemory(pBuffer, pBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, LOADFILE_ALLOCATE | LOADFILE_STORE, NULL, NULL, uBufferSize, NULL, NULL); 
          assert(nRet == ERROR_PDF_INVALID_PASSWORD); 
     
          if(nRet == ERROR_PDF_INVALID_PASSWORD) 
          { 
             // use the password for the attachment file. 
             strcpy_s((char *)pdfOptions.szPassword, _countof(pdfOptions.szPassword), "pass1"); 
             L_SetPDFOptions(&pdfOptions); 
     
             // It is not necessary to pass a LOADFILEOPTION structure anymore, since the main image is being loaded from the attachment. 
             nRet = L_LoadMemory(pBuffer, pBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, LOADFILE_ALLOCATE | LOADFILE_STORE, NULL, NULL, uBufferSize, NULL, NULL); 
          } 
     
          L_FreeBuffer(pBuffer); 
       } 
     
       return nRet; 
    } 
Help Version 21.0.2023.2.15
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Raster Imaging C API Help
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.