# Image Processor for i Documentation --- # System Requirements > Lists the supported IBM i OS versions (7.3-7.6) for Image Processor for i. ## Operating System Level Support Image Processor for i can be used on the following operating system versions: * IBM i OS 7.6 * IBM i OS 7.5 * IBM i OS 7.4 * IBM i OS 7.3 --- # Installing Image Processor for i > Step-by-step installation guide covering save file creation, FTP transfer, library restoration, PASE Python setup, and license activation. 1. Unzip the downloaded file to C:\temp (or the directory of your choice). 2. Create the *SAVF to upload to on your IBM i: `CRTSAVF FILE(QGPL/IPI) AUT(*ALL)` 3. FTP the file IPI.SAVF from your PC to the IBM i. Open a command prompt (Start → Run → type 'cmd' and preess Enter). Type the following into the command prompt, replacing the IP address with that of your IBM i. When prompted, enter your IBM i username and password. 1. `ftp 123.456.789.123` 2. `binary` 3. `lcd c:\temp` 4. `quote site namefmt 0` 5. `cd QGPL` 6. `put ipi.savf ipi.savf` 7. `quit` 4. Issue the following IBM i commands: 1. `RSTLIB SAVLIB(IPI) DEV(*SAVF) SAVF(QGPL/IPI) RSTLIB(IPI)` 2. `RST DEV('/QSYS.LIB/IPI.LIB/IFS.FILE') OBJ(('/kato/ipi' *INCLUDE '/kato/ipi')) CRTPRNDIR(*YES) PRNDIROWN(QSYS) ALWOBJDIF(*ALL)` 3. `ADDLIBLE IPI` 4. `CALL QP2TERM` 5. In the PASE shell, issue the following commands. Note that these may take multiple minutes to execute, and that you may see messages which look like errors. You can safely ignore all messages. 1. `export PATH=/QOpenSys/pkgs/bin:$PATH` 2. `yum install python3 python3-devel python3-pip python3-setuptools -y` 3. `yum install python39 python39-devel python39-wheel -y` 4. `yum install libjpeg-turbo-devel zlib-devel libtiff-devel libwebp-devel freetype-devel -y` 5. `cd /kato/ipi` 6. `python3.9 -m venv env` 7. `. env/bin/activate` 8. `pip install Pillow-8.4.0-cp39-cp39-os400_powerpc64.whl` 9. `pip list --local` After completing the last step you should receive output similar to the following: ``` Package Version ---------- ------- Pillow 8.4.0 pip 23.0.1 setuptools 58.1.0 ``` If you receive output that looks similar, execute the next command, and then press F3 to exit PASE: 10. `deactivate` 6. Registration - Apply your provided temporary or permanent license key using the below command: `APYLIC LICKEY(<>) PRODUCT(IPI)` --- # Upgrading Image Processor for i > Procedures for upgrading Image Processor for i, preserving existing configuration while restoring updated objects. **Note:** - @@ is the version number of the source/current version level (example: 10) - \### is the version number of the target/new version level (example: 20) For clarity, you may wish to copy these instructions to a text editor and then perform a scan and replace for the above values before beginning the upgrade. 1. Unzip the downloaded file to `C:\temp` (or the directory of your choice). 2. Create the \*SAVF to upload to on your IBM i: `CRTSAVF FILE(QGPL/IPI###) AUT(*ALL)` 3. FTP the file IPI.SAVF from your PC to the IBM i. Open a command prompt (Start → Run → type 'cmd' and press Enter). Type the following into the command prompt, replacing the IP address with that of your IBM i. When prompted, enter your IBM i username and password. 1. `ftp 123.456.789.123` 2. `binary` 3. `lcd c:\temp` 4. `quote site namefmt 0` 5. `cd QGPL` 6. `put ipi.savf ipi###.savf` 7. `quit` 4. Issue the following IBM i commands: 1. `RSTOBJ OBJ(*ALL) SAVLIB(IPI) MBROPT(*ALL) ALWOBJDIF(*FILELVL *OWNER) OMITOBJ((LICP) (EXAMPLE)) RSTLIB(IPI) DEV(*SAVF) SAVF(QGPL/IPI###)` 2. `RST DEV('/QSYS.LIB/IPI.LIB/IFS.FILE') OBJ(('/kato/ipi' *INCLUDE '/kato/ipi')) CRTPRNDIR(*YES) PRNDIROWN(QSYS) ALWOBJDIF(*ALL)` 3. `DLTF FILE(IPI/EXAMPLE)` 4. `RSTOBJ OBJ(EXAMPLE) OBJTYPE(*FILE) SAVLIB(IPI) MBROPT(*ALL) ALWOBJDIF(*FILELVL *OWNER) RSTLIB(IPI) DEV(*SAVF) SAVF(QGPL/IPI###)` 5. `ADDLIBLE IPI` 6. `CALL QP2TERM` 5. In the PASE shell, issue the following commands. Note that these may take multiple minutes to execute, and that you may see messages which look like errors. You can safely ignore all messages. 1. `export PATH=/QOpenSys/pkgs/bin:$PATH` 2. `yum install python3 python3-devel python3-pip python3-setuptools -y` 3. `yum install python39 python39-devel python39-wheel -y` 4. `yum install libjpeg-turbo-devel zlib-devel libtiff-devel libwebp-devel freetype-devel -y` 5. `cd /kato/ipi` 6. `rm -rf /kato/ipi/env` 7. `python3.9 -m venv env` 8. `. env/bin/activate` 9. `pip install Pillow-8.4.0-cp39-cp39-os400_powerpc64.whl` 10. `pip list --local` After completing the last step you should receive output similar to the following: ``` Package Version ---------- ------- Pillow 8.4.0 pip 23.0.1 setuptools 58.1.0 ``` If you receive output that looks similar, execute the next command, and then press F3 to exit PASE: 11. `deactivate` --- # Uninstalling Image Processor for i > Covers removing Image Processor for i by deleting the IPI library and recursively removing the IFS directory. Image Processor for i licenses may be transferred to a different IBM i, or a different partition. Part of this process will involve uninstalling the product from the original machine/partition. 1. Delete the Image Processor for i install library: `DLTLIB IPI` 2. Run QShell command to recursively remove the IPI IFS directory and everything in it: `QSH CMD('rm -Rf /kato/ipi')` --- # License Transfer > Explains how to transfer an Image Processor for i license from one IBM i system or partition to another. Image Processor for i licenses may be transferred to a different IBM i, or a different partition. To do this, you will need to provide us with screenshots of the following information with the IPI library in your library list: * The currently installed version of Image Processor for i: `DSPVER` * Machine info for each LPAR a license is being moved from: `DSPMCHINF` * Machine info for each LPAR a license is being moved to: `DSPMCHINF` If you don't currently have access to the system you're migrating to, please let us know and we can provide a temporary license until you can provide information for us to generate a permanent license key. Please email this information to isupport@katointegrations.com. --- # Image Processor for i Changelog > Version history for Image Processor for i, detailing changes per release including image format support, memory optimization, and storage model changes. ## 4.0.0 - Changing to build using `STGMDL(*TERASPACE)`. This is a **breaking** change which means that all programs calling IPI subprocs will need to either be using `STGMDL(*TERASPACE)` or `STGMDL(*INHERIT)` ## 3.0.5 - Modified IPI_ImageDS_t data structure to reduce memory usage and support eliminating some dynamic memory operations ## 3.0.4 - Further reduced static storage usage ## 3.0.3 - Corrected additional memory usage issues including moving all internal pointers to teraspace - Significantly reduced overall static storage usage ## 3.0.2 - Corrected a variety of memory/pointer issues that could lead to memory leaks ## 3.0.1 - IPI will now try to locate IPICFGOPT in the *LIBL, and if not found will attempt to check the current program library for IPICFGOPT ## 3.0.0 - Internal rewrite to leverage Python libraries from PASE environment to handle image conversion - Now supports more input image formats including JPEG, PNG, GIF, TIF - Default installation directory is now `/kato/ipi` - New database configuration file IPICFGOPT added - IPICB copybook now provided in free format ## 2.00 - Improved image loading to allow for STMF or RPG field as source of image data - [New] Added capability to automatically Base64 decode provided image data - [New] Added capability to control specific dimensions of created page segment ## 1.10 - Corrected issues with image loading. ## 1.00 - Initial release. --- # IPI_Initialize() > Initialises the IPI environment; must be called before any other IPI subprocedure in a program. This subprocedure is used to initialize the internal IPI environment to allow the usage of other IPI subprocedures. This subprocedure must be called prior to any other IPI subprocedures. ## Subprocedure Prototype | Field | Description | |---|---| | `Dcl-Pr IPI_Initialize Ind OpDesc ExtProc('IPI_Initialize');` | Returns *OFF if an error occurs during processing, *ON otherwise. | | ` pErrorDS LikeDS(IPI_ErrorDS_t) Options(*NoPass:*Omit);` | Optional parameter that, if passed, will contain error data returned from the subprocedure. If it is not passed, exceptions will instead be "thrown" and must be caught by a MONITOR block. | | `End-Pr;` | | ## Data Structures ### IPI_ErrorDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ErrorDS_t Qualified Template Inz;` | | | ` Subproc VarChar(132);` | Subprocedure which received error | | ` MessageCode Char(7);` | Message ID of error message | | ` Message VarChar(1024);` | Error message text | | `End-Ds;` | | --- # IPI_Terminate() > Terminates the IPI environment and releases resources; must be called once all IPI operations in a program are complete. This subprocedure is used to terminate the internal IPI environment. This should be called once all IPI operations have been completed at the end of your program. ## Subprocedure Prototype | Field | Description | |---|---| | `Dcl-Pr IPI_Terminate Ind OpDesc ExtProc('IPI_Terminate');` | Returns *OFF if an error occurs during processing, *ON otherwise. | | ` pErrorDS LikeDS(IPI_ErrorDS_t) Options(*NoPass:*Omit);` | Optional parameter that, if passed, will contain error data returned from the subprocedure. If it is not passed, exceptions will instead be "thrown" and must be caught by a MONITOR block. | | `End-Pr;` | | ## Data Structures ### IPI_ErrorDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ErrorDS_t Qualified Template Inz;` | | | ` Subproc VarChar(132);` | Subprocedure which received error | | ` MessageCode Char(7);` | Message ID of error message | | ` Message VarChar(1024);` | Error message text | | `End-Ds;` | | --- # IPI_LoadImage() > Loads an image from an RPG field, STMF file, or Base64-encoded value and returns an image data structure for use in subsequent IPI operations. This subprocedure is used to load an image from either a character field or a STMF. The loaded image can then be used to perform other IPI operations such as [IPI_ImageToPageSegment()](https://isupport.katointegrations.com/llms/ipi_imagetopagesegment.md). Images can be loaded from: * A provided RPG field in the pImageData parameter. * A STMF specified on the Stmf subfield of the IPI_LoadImageDS_t parameter Many times an image may be Base64 encoded such as if it was received via a web service. IPI_LoadImage() can decode a Base64 encoded image and then proceed to load it if the Base64Encoded subfield of the IPI_LoadImageDS_t parameter is set to IPI_YES. If the image is not Base64 encoded, this subfield should be set to IPI_NO. Once the image has been loaded, an IPI_ImageDS_t data structure will be returned. This is used to provide important information about the image to other IPI subprocedures. ## Subprocedure Prototype | Field | Description | |---|---| | `Dcl-Pr IPI_LoadImage Ind ExtProc('IPI_LoadImage');` | Returns *OFF if an error occurs during processing, *ON otherwise. | | ` pImageDS LikeDS(IPI_ImageDS_t);` | Return parameter that contains the loaded image which can be used with other IPI subprocedures. | | ` pLoadImageDS LikeDS(IPI_LoadImageDS_t) Const;` | Controls how the image data is loaded and can be used to provide an IFS STMF to load data from. | | ` pImageData VarChar(16773100:4) Const Options(*Omit:*VarSize);` | May be used to pass image data | | ` pErrorDS LikeDS(IPI_ErrorDS_t) Options(*NoPass:*Omit);` | Optional parameter that, if passed, will contain error data returned from the subprocedure. If it is not passed, exceptions will instead be "thrown" and must be caught by a MONITOR block. | | `End-Pr;` | | ## Data Structures ### IPI_LoadImageDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_LoadImageDS_t Qualified Template Inz;` | | | ` Base64Encoded Ind Inz(IPI_YES);` | **Default Value:** `IPI_YES` **Valid Values:** `IPI_YES`, `IPI_NO` | | ` Stmf VarChar(8192);` | Specifies a path to a STMF in the IFS where image data should be loaded from. | | ` InputCcsid Int(10) Inz(IPI_CCSID_JOB);` | **Default Value:** `IPI_CCSID_JOB` | | ` ImagePointer Pointer Inz(*Null);` | **Internal use only** | | ` ImagePointerLength Uns(10);` | **Internal use only** | | `End-Ds;` | | ### IPI_ImageDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ImageDS_t Qualified Template Inz;` | | | ` Image Pointer Inz(*Null);` | **Internal use only** | | ` MaxSize Uns(10);` | **Internal use only** | | ` UsedSize Uns(10);` | **Internal use only** | | ` Format Char(8);` | **Internal use only** | | `End-Ds;` | | ### IPI_ErrorDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ErrorDS_t Qualified Template Inz;` | | | ` Subproc VarChar(132);` | Subprocedure which received error | | ` MessageCode Char(7);` | Message ID of error message | | ` Message VarChar(1024);` | Error message text | | `End-Ds;` | | --- # IPI_UnloadImage() > Unloads a previously loaded image and frees its associated memory; must be called before IPI_Terminate(). This subprocedure is used to unload an image that was previously loaded using [IPI_LoadImage()](https://isupport.katointegrations.com/llms/ipi_loadimage.md). This should be called to free memory associated with the loaded image prior to calling [IPI_Terminate()](https://isupport.katointegrations.com/llms/ipi_terminate.md). ## Subprocedure Prototype | Field | Description | |---|---| | `Dcl-Pr IPI_UnloadImage Ind ExtProc('IPI_UnloadImage');` | Returns *OFF if an error occurs during processing, *ON otherwise. | | ` pImageDS LikeDS(IPI_ImageDS_t);` | Contains image data previously loaded by IPI_LoadImage() | | ` pErrorDS LikeDS(IPI_ErrorDS_t) Options(*NoPass:*Omit);` | Optional parameter that, if passed, will contain error data returned from the subprocedure. If it is not passed, exceptions will instead be "thrown" and must be caught by a MONITOR block. | | `End-Pr;` | | ## Data Structures ### IPI_ImageDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ImageDS_t Qualified Template Inz;` | | | ` Image Pointer Inz(*Null);` | **Internal use only** | | ` MaxSize Uns(10);` | **Internal use only** | | ` UsedSize Uns(10);` | **Internal use only** | | ` Format Char(8);` | **Internal use only** | | `End-Ds;` | | ### IPI_ErrorDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ErrorDS_t Qualified Template Inz;` | | | ` Subproc VarChar(132);` | Subprocedure which received error | | ` MessageCode Char(7);` | Message ID of error message | | ` Message VarChar(1024);` | Error message text | | `End-Ds;` | | --- # IPI_ImageToPageSegment() > Converts a loaded image into an AFPDS page segment (*PAGSEG) object on IBM i with configurable width and height dimensions. This subprocedure is used to convert an image which was previously loaded by [IPI_LoadImage()](https://isupport.katointegrations.com/llms/ipi_loadimage.md) into a page segment (*PAGSEG) which can be used with AFPDS printing on the IBM i. The dimensions of the page segment being created can be specified in inches using the Width and Height subfields of the IPI_PageSegmentDS_t to resize the output. ## Subprocedure Prototype | Field | Description | |---|---| | `Dcl-Pr IPI_ImageToPageSegment Ind ExtProc('IPI_ImageToPageSegment');` | Returns *OFF if an error occurs during processing, *ON otherwise. | | ` pImageDS LikeDS(IPI_ImageDS_t) Const;` | Contains image data previously loaded by IPI_LoadImage() | | ` pTargetPageSegmentDS LikeDS(IPI_PageSegmentDS_t) Const;` | Contains configuration information about the page segment to create. | | ` pErrorDS LikeDS(IPI_ErrorDS_t) Options(*NoPass:*Omit);` | Optional parameter that, if passed, will contain error data returned from the subprocedure. If it is not passed, exceptions will instead be "thrown" and must be caught by a MONITOR block. | | `End-Pr;` | | ## Data Structures ### IPI_ImageDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ImageDS_t Qualified Template Inz;` | | | ` Image Pointer Inz(*Null);` | **Internal use only** | | ` MaxSize Uns(10);` | **Internal use only** | | ` UsedSize Uns(10);` | **Internal use only** | | ` Format Char(8);` | **Internal use only** | | `End-Ds;` | | ### IPI_PageSegmentDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_PageSegmentDS_t Qualified Template Inz;` | | | ` ObjectName Char(10);` | Specify the object name used to create the page segment | | ` LibraryName Char(10) Inz('*LIBL');` | Specify the library where the page segment will be created **Default Value:** `*LIBL` | | ` Width Packed(5:3);` | Specify the desired output width in inches | | ` Height Packed(5:3);` | Specify the desired output height in inches | | `End-Ds;` | | ### IPI_ErrorDS_t | Field | Description | |---|---| | `Dcl-Ds IPI_ErrorDS_t Qualified Template Inz;` | | | ` Subproc VarChar(132);` | Subprocedure which received error | | ` MessageCode Char(7);` | Message ID of error message | | ` Message VarChar(1024);` | Error message text | | `End-Ds;` | | --- # APYLIC - Apply License > Applies a permanent or temporary license key to the Image Processor for i installation. To apply a permanent or temporary license key, you will use the included command APYLIC. Your license key will typically be supplied via email in a command string: `APYLIC LICKEY(6E2222898982C8F1380F4DF08A23922C) PRODUCT(IPI)` Or, you can copy and paste the received key into the command: ![Apply License (APYLIC)](https://isupport.katointegrations.com/llms/image-processor-for-i/apylic.png "Apply License (APYLIC)") In either case after running the APYLIC command, you should receive a message that says **License applied successfully** If you don't receive that message or receive an error message, please contact us at isupport@katointegrations.com. --- # DSPLIC - Display License > Legacy alias for DSPMCHINF; displays machine and license information needed for activation key generation. DSPLIC is used to retrieve system information as well as license status. **Note:** [Display Machine Info (DSPMCHINF)](https://isupport.katointegrations.com/llms/dspmchinf.md) is an alias for this command. These commands may be used interchangeably. The command does not have any parameters: `DSPLIC` The command should display a screen similar to the one below. This screen indicates all the information necessary to generate your license key, as well as the current status of any applied license keys. ![Display License (DSPLIC)](https://isupport.katointegrations.com/llms/image-processor-for-i/dsplic.png "Display License (DSPLIC)") If you don't receive that message or receive an error message, please contact us at isupport@katointegrations.com. --- # DSPMCHINF - Display Machine Info > Displays system machine information and license key status required by support to generate activation keys. DSPMCHINF is used to retrieve system information as well as license status. **Note:** DSPMCHINF is an alias for the [Display License (DSPLIC)](https://isupport.katointegrations.com/llms/dsplic.md) command. These commands may be used interchangeably. The command does not have any parameters: `DSPMCHINF` The command should display a screen similar to the one below. This screen indicates all the information necessary to generate your license key, as well as the current status of any applied license keys. ![Display Machine Info (DSPMCHINF)](https://isupport.katointegrations.com/llms/image-processor-for-i/dspmchinf.png "Display Machine Info (DSPMCHINF)") If you don't see this screen or receive an error message, please contact us at isupport@katointegrations.com. --- # DSPVER - Display Version > Displays the currently installed version of Image Processor for i. DSPVER can be used to retrieve the version number of the currently installed product. The command does not have any parameters: `DSPVER` You should receive a message indicating the currently installed version as well as the library in which the product is installed. ![Display Version (DSPVER)](https://isupport.katointegrations.com/llms/image-processor-for-i/dspver.png "Display Version (DSPVER)") If you don't receive that message or receive an error message, please contact us at isupport@katointegrations.com. --- # Create Page Segment from STMF > RPG example showing how to load an image from the IFS and create a page segment with specified dimensions using IPI_LoadImage() and IPI_ImageToPageSegment(). ```rpgle *------------------------------------------------------------------------ * @Author: Kato Integrations * @Description: * This is a test program demonstrating how to call IPI APIs to * create a page segment (*PAGSEG) from a provided image file in the * IFS. You can specify the dimensions of the page segment being created * in inches. *------------------------------------------------------------------------ H DFTACTGRP(*NO) ACTGRP(*CALLER) BNDDIR('IPIBND') OPTION(*NODEBUGIO) /COPY QRPGLECPY,IPICB // This is included for demo output purposes only and is not part of IPI. D WriteToJobLog PR 10I 0 Extproc('Qp0zLprintf') D pString * Value Options(*String) D NewLine C x'15' // This data structure will contain any error information returned by // the IPI APIs. D IPIErrorDS DS LikeDS(IPI_ErrorDS_t) Inz(*LikeDS) // This data structure is used to configure how image data is loaded as // well as whether or not the image is coming from a STMF or a field. D LoadImageDS DS LikeDS(IPI_LoadImageDS_t) D Inz(*LikeDS) // This data structure is used to pass around information about a loaded // image to other IPI APIs for further processing or output. D ImageDS DS LikeDS(IPI_ImageDS_t) D Inz(*LikeDS) // This data structure configures where the page segment will be // created and allows you to specify the target dimensions of the // page segment in inches. D TargetPagSegDS DS LikeDS(IPI_PageSegmentDS_t) D Inz(*LikeDS) /FREE // Always call IPI_Initialize() before calling any other IPI APIs. // IPI_Initialize() will return *On if it was successful or *Off if not reset IPIErrorDS; if not IPI_Initialize( IPIErrorDS ); // handle error here WriteToJobLog( 'IPI_Initialize() Error' + NewLine ); WriteToJobLog( 'Error Message ID: ' + IPIErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + IPIErrorDS.Message + NewLine ); exsr cleanup; return; endif; // Always reset IPI data structures before using them. reset ImageDS; reset LoadImageDS; // Set which IFS image file to create a page segment from LoadImageDS.Stmf = '/tmp/image.tiff'; // Is the input data base64 encoded? LoadImageDS.Base64Encoded = IPI_NO; reset IPIErrorDS; if not IPI_LoadImage( ImageDS : LoadImageDS : *Omit : IPIErrorDS ); // handle error here WriteToJobLog( 'IPI_LoadImage() Error' + NewLine ); WriteToJobLog( 'Error Message ID: ' + IPIErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + IPIErrorDS.Message + NewLine ); exsr cleanup; return; endif; // Specify location of created page segment reset TargetPagSegDS; TargetPagSegDS.ObjectName = 'IPITSTPS'; TargetPagSegDS.LibraryName = 'IPI'; // Width in inches TargetPagSegDS.Width = 2.00; // Height in inches TargetPagSegDS.Height = 1.00; reset IPIErrorDS; if not IPI_ImageToPageSegment( ImageDS : TargetPagSegDS : IPIErrorDS ); // handle error here WriteToJobLog( 'IPI_ImageToPageSegment() Error' + NewLine ); WriteToJobLog( 'Error Message ID: ' + IPIErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + IPIErrorDS.Message + NewLine ); exsr cleanup; return; endif; exsr cleanup; *INLR = *ON; return; begsr cleanup; // You need to call IPI_UnloadImage() on every image loaded using // IPI_LoadImage() to ensure all memory is freed correctly. IPI_UnloadImage( ImageDS ); // It is important to call IPI_Terminate() at the end of your program // This includes when an error occurs. IPI_Terminate(); endsr; /END-FREE ``` --- # Create Page Segment from RPG Field > RPG example demonstrating how to load an image from a database field and convert it to a page segment using IPI_LoadImage() and IPI_ImageToPageSegment(). ```rpgle *------------------------------------------------------------------------ * @Author: Kato Integrations * @Description: * This is a test program demonstrating how to call IPI APIs to * create a page segment (*PAGSEG) from a provided image in a field, * such as one loaded from a DB2 file. You can specify the dimensions * of the page segment being created in inches. *------------------------------------------------------------------------ H DFTACTGRP(*NO) ACTGRP(*CALLER) BNDDIR('IPIBND') OPTION(*NODEBUGIO) /COPY QRPGLECPY,IPICB // This is included for demo output purposes only and is not part of IPI. D WriteToJobLog PR 10I 0 Extproc('Qp0zLprintf') D pString * Value Options(*String) D NewLine C x'15' // This data structure will contain any error information returned by // the IPI APIs. D IPIErrorDS DS LikeDS(IPI_ErrorDS_t) Inz(*LikeDS) // This data structure is used to configure how image data is loaded as // well as whether or not the image is coming from a STMF or a field. D LoadImageDS DS LikeDS(IPI_LoadImageDS_t) D Inz(*LikeDS) // This data structure is used to pass around information about a loaded // image to other IPI APIs for further processing or output. D ImageDS DS LikeDS(IPI_ImageDS_t) D Inz(*LikeDS) // This data structure configures where the page segment will be // created and allows you to specify the target dimensions of the // page segment in inches. D TargetPagSegDS DS LikeDS(IPI_PageSegmentDS_t) D Inz(*LikeDS) D Image S 8192A Varying /FREE // Always call IPI_Initialize() before calling any other IPI APIs. // IPI_Initialize() will return *On if it was successful or *Off if not reset IPIErrorDS; if not IPI_Initialize( IPIErrorDS ); // handle error here WriteToJobLog( 'IPI_Initialize() Error' + NewLine ); WriteToJobLog( 'Error Message ID: ' + IPIErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + IPIErrorDS.Message + NewLine ); exsr cleanup; return; endif; // Always reset IPI data structures before using them. reset ImageDS; reset LoadImageDS; // Is the input data base64 encoded? LoadImageDS.Base64Encoded = IPI_NO; // Is the image data in a CCSID other than the job CCSID? If so, // specify it in the below subfield. Note that there are other // CCSID constants in QRPGLECPY,IPICB but ones not defined in the // copybook may also be used as well. LoadImageDS.InputCcsid = IPI_CCSID_JOB; reset IPIErrorDS; // Image would be the image data as loaded from your source - such as // from a DB2 file, a webservice, from the IFS, etc. Image = ''; if not IPI_LoadImage( ImageDS : LoadImageDS : Image : IPIErrorDS ); // handle error here WriteToJobLog( 'IPI_LoadImage() Error' + NewLine ); WriteToJobLog( 'Error Message ID: ' + IPIErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + IPIErrorDS.Message + NewLine ); exsr cleanup; return; endif; // Specify location of created page segment reset TargetPagSegDS; TargetPagSegDS.ObjectName = 'IPITSTPS'; TargetPagSegDS.LibraryName = 'IPI'; // Width in inches TargetPagSegDS.Width = 2.00; // Height in inches TargetPagSegDS.Height = 1.00; reset IPIErrorDS; if not IPI_ImageToPageSegment( ImageDS : TargetPagSegDS : IPIErrorDS ); // handle error here WriteToJobLog( 'IPI_ImageToPageSegment() Error' + NewLine ); WriteToJobLog( 'Error Message ID: ' + IPIErrorDS.MessageId + NewLine ); WriteToJobLog( 'Error Message: ' + IPIErrorDS.Message + NewLine ); exsr cleanup; return; endif; exsr cleanup; *INLR = *ON; return; begsr cleanup; // You need to call IPI_UnloadImage() on every image loaded using // IPI_LoadImage() to ensure all memory is freed correctly. IPI_UnloadImage( ImageDS ); // It is important to call IPI_Terminate() at the end of your program // This includes when an error occurs. IPI_Terminate(); endsr; /END-FREE ```