OP_D2S, OP_D2SE, OP_D2SEPLUS: Compress DIB to sequential JPEG
- OP_D2S provides baseline JPEG compression.
- OP_D2SE adds support for compression using the Accusoft enhanced coding algorithm (known as the ELS coder).
- OP_D2EPLUS adds support for compression of grayscale data up to 12bpp.
See the DIB_INPUT: OP_D2S section for additional information. In particular, the values for 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. The PIC_PARM Head structure must have valid BITMAPINFO data for the DIB prior to REQ_INIT. If Head.biBitCount is 4 or 8, then ColorTable must be initialized to the DIBs color table so that the DIB pixel color values can be correctly evaluated.
Input formats (Head.biCompression) are BI_RGB (4/8/16/24/32 bpp RGB and 4/8 bpp gray), BI_RGB565 (16-bit RGB 5-6-5), BI_RGBA (32 bit RGB compressed with alpha channel), BI_CMYK (32-bit compressed as 4-component), BI_GR12 (9-16 bit gray compressed as 12-bit JPEG -- OP_D2SEPLUS only), BI_UYVY, BI_YUY2, BI_YV12, or BI_IYUV (planar and interleaved YUV formats). Set Head.biCompression to BI_RGBA to compress a 32-bit RGBA image as a 4-component JPEG image by also compressing the alpha channel information. Planar YUV formats require that the entire image be present in the Get queue before compression.
This opcode provides allows the image data to be protected using a key provided by the application. See details in the section describing the PIC_PARM KeyField field.
Color JPEG Output Image
A. No color table in output, standard JFIF output
- Set Head.biClrUsed to 0. Note that this works even if the input image is a 4-bit or 8-bit DIB. Pegasus uses the image pixel color indices to index ColorTable regardless of the setting of Head.biClrUsed. Head.biClrUsed does determine whether or not a color table is saved with the output JPEG image.
- PF_MakeColors is not set.
- PF_IsGray is not set.
- PF_App1Pal is not set.
- PF_UseYCbCrForColors is not set.
- PrimClrToMake and SecClrToMake are not used.
- If RAW B-G-R input, specify PF_WidthPadKnown and set the u.D2J.WidthPad to the number of bytes in a scan line.
- If the RAW color order is not B-G-R, use PF_SwapRB
B. Input is DICOM YBR_FULL_422
The DICOM specification uses the identifier YBR_FULL_422 to specify that the YBR pixels are subsampled 4-2-2 (equivalent to Pegasus 2-1-1), that the subsampling is cosited, and that the input pixel component sample intensities range from 0 to 255. This is in conflict with the JFIF specification which specifies that the subsampling is averaged and not cosited. In order to create DICOM-compliant color jpeg images from YBR_FULL_422 input images, the following steps are taken:
Input is BI_YUY2 or BI_UYVY
- Follow A. above (no color table in output image)
- Specify subsampling of 2-1-1 Horizontal (SS_211)
- Set PF2_Cosited
- Set bit 0 of p.u.D2J.AppsToOmit to omit the JFIF App0 marker
- Set Head.biCompression to BI_YUY2 or BI_UYVY
- Set Head.biBitCount to 16
C. Input is DICOM YBR_PARTIAL_422
The DICOM specification uses the identifier YBR_FULL_422 to specify that the YBR pixels are subsampled 4-2-2 (equivalent to Pegasus' 2-1-1), that the subsampling is cosited, and that the input pixel component Y sample intensities range from 16 to 235 and Cb and Cr sample intensities range from 16 to 240. This is in conflict with the JFIF specification for which specifies that the subsampling is averaged and not cosited. In order to create DICOM-compliant color jpeg images from YBR_PARTIAL_422 input images, the following steps are taken:
Input is BI_YUY2 or BI_UYVY
- Follow A. above (no color table in output image)
- Specify subsampling of 2-1-1 Horizontal (SS_211)
- Set PF2_Cosited
- Set PF2_CompressedYUV
- Set bit 0 of p.u.D2J.AppsToOmit to omit the JFIF App0 marker
- Set Head.biCompression to BI_YUY2 or BI_UYVY
- Set Head.biBitCount to 16
D. Output is CMYK Color JPEG
CMYK JPEG files can be created from CMYK input color data
Input is interleaved C-M-Y-K
- Follow A. above (no color table in output image)
- Specify subsampling of 1-1-1 (SS_111)
- Set Head.biCompression to BI_CMYK
- Set Head.biBitCount = 32
- Set Head.biHeight to - (Height in lines)
- Set p.u.D2J.WidthPad to size in bytes of line
- Set Head.biSizeImage to WidthPad * Height in lines
- Set PF_WidthPadKnown
- Set PF_NoDIBPad
- Set bit 0 of p.u.D2J.AppsToOmit to omit the JFIF App0 marker
Gray Scale JPEG Output Image from Color DIB Input
This can't be done directly with this opcode. The DIB must first be converted to gray scale before being compressed.
Gray Scale JPEG Output Image from Gray Scale DIB or RAW Input
A. 1-8 bpp gray DIB data
- Set Head.biClrUsed to 0. Note that this works even if the input image is a 4-bit or 8-bit DIB. Pegasus uses image pixel color indices to index ColorTable regardless of the setting of Head.biClrUsed. Head.biClrUsed does determine whether or not a color table is saved with the output JPEG image.
- PF_MakeColors is not set.
- PF_IsGray is set.
- PF_App1Pal is not set.
- PF_UseYCbCrForColors is not set.
- PrimClrToMake and SecClrToMake are not used.
B. 1-8 bpp gray RAW data
- Set Head.biClrUsed to 0. Pegasus uses image pixel color indices to index ColorTable regardless of the setting of Head.biClrUsed. Head.biClrUsed does determine whether or not a color table is saved with the output JPEG image.
- Set Head.biCompression to BI_RGB.
- Set Head.biBitCount to 8.
- Set Head.biHeight to the height in Rows.
- Set WidthPad to the width in bytes of one line (Stride).
- Set Head.biSizeImage to WidthPad * Height in lines.
- Set PF_WidthPadKnown.
- PF_MakeColors is not set.
- PF_IsGray is set.
- PF_App1Pal is not set
- PF_UseYCbCrForColors is not set.
- PrimClrToMake and SecClrToMake are not used.
C. 9 - 12 bpp gray RAW data
- Up to 12 bpp (inclusive) gray data lossy jpeg compression is supported with the OP_D2SEPLUS opcode.
- The 12-bit data is assumed to be in 16-bit words. By default it is assumed that the 12 bits are right-justified in the 16-bit field. Set D2J.RightShift12 to a number between 0 and 4 inclusive, to right-shift the input words by this amount to get the 12 bits properly located. For example, if the data is left-justified, set D2J.RightShift12 to 4; the words will be right-shifted by 4 bits, discarding the low-order 4 bits, leaving 12 bits in the proper position.
- If the data in the words is actually less than 12 bits, e.g. 10 bits, compress as if it were 12 bit. The decompressor should be set to handle this also, however, to insure that the lossy decompressed data is trimmed to 10 bits.
- Head.biWidth is set to the image width in pixels.
- Head.biHeight is set to the image height in pixels.
- Head.biImageSize is set to the image_width * image_height.
- Head.biCompression is set to BI_GR12.
- Head.biBitCount is set to 16 (this is the dib-size, even though 12 of the bits are meaningful).
- PF_IsGray is set.
- PF_NoDibPad is set. (Otherwise, it is assumed that the input lines are padded to a multiple of 4 bytes in width).
- If the line size in bytes is not equal to 2*image_width (for example if the lines are padded, or if compressing a sub-rectangle of a larger image), set D2J.WidthPad to the actual line size in bytes, and set PF_WidthPadKnown. This overrides PF_NoDibPad flag if set.
- PF_OptimizeHuffCodes is set (if not set, a default huffman table is used; but this is not a 'standard' because there is no standard table for 12-bit data).
- Set D2J.JpegType to JT_RAW.
- Get.Front should be set to the beginning of the raw data.
- A custom quantization table may be used by having D2J.QTable point to it; this may be either 64 bytes if all quantization values are in the range 0-255, or may be 64 words (16-bit items) if quantization values are between 0 and 2^15 - 1 . In the word case, set PF_WordQtbl. The Qtable values are not in zig-zag order, just ordinary row order.
- If not using a custom qtable, set D2J.LumFactor to a number between 0 and 255 inclusive. 0 is the highest quality, giving a quantization table of all 1's. 32 corresponds to the standard quantization tables. For values between 0 and 128, the standard tables are scaled linearly. For values between 128 and 255, the standard tables are scaled non-linearly and the compression increases (and the quality decreases) by a very large amount.
- To omit the JFIF App0 marker, set bit 0 of D2J.AppsToOmit; to omit the PIC App1 marker, set bit 1 of D2J.AppsToOmit. Thus if D2J.AppsToOmit = 3, neither APP marker appears in the output.
- Note that Els Coder is not allowed for 12-bit data.
Metadata
JPEG metadata can be added to the JPEG image by supplying metadata in the PIC2List. The following metadata operations are supported:
- APP marker segments can be added by inserting APP marker data as P2P_RawData packets in the PIC2List passed to the opcode.
- APP13 marker segments can contain IPTC data and therefore receive unique handling. If multiple APP13 marker segments are provided, the opcode will attempt to combine the segments into a single APP13 segment. If the single APP13 segment exceeds the maximum allowed segment size, it will be divided into smaller segments as needed.
- IPTC data can be added by inserting IPTC data into the PIC2List with the P2LAddIPTCDataSet function. See the PIC2List IPTCDataSet Packet Functions.
- When IPTC data is edited, the following processing takes place:
- Multiple IPTC packets are combined into a single IPTC resource block.
- Duplicate IPTC data is removed.
- When possible, mandatory IPTC data is added if it is not already present.
- XMP data present in an APP13 segment will be removed.
- XMP data present in an APP1 segment will be removed.
- Caption Digest data present in an APP13 segment will be removed.
- The IPTC data that is present in the PIC2List as P2PktIPTCDataSet packets always takes precedent over any IPTC data that may be embedded in APP13 marker segments. For example:
- If the PIC2List contains an APP13 segment that does not contain IPTC data, but IPTC data is present as P2PktIPTCDataSet packets, then that IPTC data will be added to the APP13 segment.
- If the PIC2List contains an APP13 segment that does contain IPTC data, but IPTC data is not present as P2PktIPTCDataSet packets, then the IPTC data will be removed from the APP13 segment.
- If the PIC2List contains an APP13 segment that does contain IPTC data and IPTC data is present as P2PktIPTCDataSet packets, but this data differs from the IPTC data in the APP13 segment, then IPTC data in the APP13 segment will be replaced with the IPTC data in the P2PktIPTCDataSet packets.
- It is possible, though unlikely, for an IPTC packet to be constructed by this opcode that spans multiple APP13 segments. If this happens, this IPTC packet will not be able to be read by the OP_RORE, OP_S2D, OP_SE2D, or OP_SE2DPLUS opcodes.
Notes
- The Put queue is accessed during REQ_INIT.
- The Put queue can be allocated during the REQ_INIT response loop if desired.
- The Put queue size must be at least 1K.
- The Get queue size must be an integral multiple of u.S2D.StripSize unless it is large enough for the entire image.
- The Get queue is not accessed during REQ_INIT.
- The Get queue must have been allocated prior to REQ_EXEC.