OP_D2PDF: Inserts a DIB Into A PDF File
OP_D2PDF supports creation of PDF files from an input DIB and appending of an input DIB to existing PDF files. (See opcode specific data structure.)
General Notes
- The input image will be compressed according to the Compression member of PDF_UNION. OP_D2PDF can compress an input DIB with:
- No compression (1, 8, and 24 bit per pixel)
- CCITT G3 1-Dimensional (1 bit per pixel, black and white)
- CCITT G3 2-Dimensional (1 bit per pixel, black and white)
- CCITT G4 (1 bit per pixel, black and white)
- JBIG2 - Lossy and Lossless (1 bit per pixel, black and white)
- Sequential JPEG (4 and 8 bit indexed, 16 5/5/5, 16 5/6/5, 24, 32 RGBA, and 32 CMYK)
- JPEG2000 (8 bit indexed, 24 RGB, and 32 RGBA)
- Setting the Compression member to PDFCompress_Default or 0 will indicate to use CCITT G4 encoding for 1 bit, black and white images and sequential JPEG encoding for all other valid input types.
- All Head and ColorTable data must be initialized in the PIC_PARM structure prior to calling REQ_INIT.
- PDF files are created using version 1.4 of the PDF file specification for all compression modes other than JPEG2000 If JPEG2000 compression is selected, a version 1.5 file is generated. Appending to files conforming to version 1.0, 1.1, 1.2, and 1.3, 1.4, and 1.5 of the PDF file specification is supported.
- PF_YieldGet may be set if the RES_GET_DATA_YIELD response is desired.
- If 1 bit per pixel, the file will be compressed with 0 pixels treated as black if *(DWORD*)&ColorTable[0] is 0, otherwise 0 pixels will be treated as white.
- If using JBIG2 compression, EncodeModeJBIG2 may be set to specify the encoding method for the JBIG2 region. OP_D2PDF does not support multiple regions on a single page, and the encode mode specified will apply to the entire page. PageFlagsJBIG2, RegionFlagsJBIG2 and Looseness are set to control the JBIG2 compression.
- If using sequential JPEG compression, LumFactor, ChromFactor and SubSampling can be adjusted to increase the compression ratio with lower image quality, or to decrease the compression ratio with higher image quality.
- If using sequential JPEG compression, all image types are encoded as a 24 bit images except for 8-bit gray scale images when the PF_IsGray flag is set. These are encoded as 8-bit gray scale JPEG.
- PF_SwapRB may be set to indicate the input data is in RGB order instead of BGR.
- If using sequential JPEG or JPEG2000 compression, PF2_NoYccTransform may be set to indicate RGB values should not be converted to YCC for 24-bit and YCCK for 32-bit images prior to encoding.
- If using sequential JPEG compression, PF2_AcrobatCmyk may be set to indicate CMYK compression should be compatible with Acrobat instead of being compatible with Photoshop. See PDF_UNION for additional details.
- If using JPEG2000 compression, the PF2_ForceLossless flag can be set to compress the image losslessly. If PF2_ForceLossless is not specified for 8 bit indexed input (color only), the indexed input will be converted to 24 bit RGB prior to compression. If the input DIB is 8 bit indexed with a uniform gray map, the image is compressed as a gray image. See OP_J2KP for more information.
- If using JPEG2000 compression, Rate, CompFileSize, and TargetPSNR can be adjusted to control the degree of compression in lossy mode. See OP_J2KP and PDF_UNION for more information.
- For compression, this opcode uses other opcodes, depending on the method of compression. The compressor opcode registration data is passed to this opcode in the PicParm.PIC2List P2PktRegistration packets. See the PIC2List Functions section for more information.
PDF File Creation
In order to create a PDF file containing the encoded DIB, you must make this input image available in the Get queue, and after encoding; a valid PDF file will be placed in the Put queue. Q_EOF is set on the Put queue once the PDF file is created. At least StripSize bytes must be made available in the Get queue upon REQ_EXEC. See the PDF_UNION structure for additional information.
PDF File Appending
A DIB can be appended to an existing PDF file by setting PF_MultiImage in PDF.PicFlags. The existing PDF file is supplied to OP_D2PDF using the Put queue. The Put queue does not have to be large enough to hold the entire PDF file, but in this case, support for seeking is required. Q_REVERSE is not supported for the Put queue for this operation since PDF reading requires a top-down approach. In the first case considered in the following, the Put queue is large enough to hold the entire existing PDF file. In the second case, the Put queue is too small to hold the entire existing PDF file.
Large enough Put queue:
In this case, read the existing file into the Put queue beginning at Put.Start, setting Put.Front to Put.Start, Put.Rear to the first byte following the file data and setting Q_EOF in Put.QFlags. If the Put queue is not large enough for the existing file and the incremental update, RES_PUT_NEED_SPACE events will be returned as usual and can be handled normally. In that case, the Put queue can either be reallocated to a larger size or the Put queue data can be written to an output PDF file beginning at file offset 0, advancing Put.Front to the first byte of data not written.
Put queue too small:
In this case, things are more complicated because existing file data is supplied using the Put queue and output file data is returned using the same Put queue.
Initially, the location pointed to be Put.Front is presumed to correspond to offset 0 in the existing PDF file. When RES_PUTQ_GET_NEED_DATA is returned, the Put queue will be empty. You should read up to Put.End - Put.Start bytes of data from the existing PDF file into the Put queue at Put.Start starting at file offset SeekInfo & SEEK_OFFSET. Set Put.Front to Put.Start and set Put.Rear to point to the byte following the last byte read from the existing file. Set Q_EOF in Put.QFlags if the end of the existing file is reached. Finally, restore the file offset to SeekInfo & SEEK_OFFSET. This is so a RES_PUT_NEED_SPACE can unconditionally be written to the file at the current file offset.
SeekInfo is set during RES_PUTQ_GET_NEED_DATA as a convenience. Successive RES_PUTQ_GET_NEED_DATA responses will always be sequentially contiguous in the existing file unless a RES_SEEK response is returned.
A RES_SEEK response will only be returned when the Put queue is empty. In that case, set the current file offset to SeekInfo & SEEK_OFFSET.
A RES_PUT_NEED_SPACE response can be handled as normally. Alternatively, if Q_READING is set in Put.QFlags, then the queue data was not modified by OP_D2PDF. In that case, if the queue data are available at another location, the queue data can optionally be discarded instead of written.