Operations > OP_LIE3, OP_LIE3PLUS |
OP_LIE3, OP_LIE3PLUS: Expand Lossless JPEG and IMStar to DIB or RAW
See the LOSSLESS3:OP_LIE3 section for additional information.
OP_LIE3 is used to expand Lossless JPEG and IMStar images with varying grayscale and color bit depths. Lossless JPEG images can be in a JPEG file format or PIC2 file format. IMStar compressed images must be in PIC2 file format. The compression method is reported in u.LL3.CompMethod:
OP_LIE3PLUS adds the ability to decompress grayscale data up to 16bpp, inclusive and images compressed as planar with RGB planes.
The decompression process follows the familiar REQ_INIT, REQ_EXEC, REQ_TERM sequence of calls to Pegasus. Before REQ_INIT, some image data is placed in a Get buffer and a PIC_PARM structure, pic_parm, is allocated and its basic structure members initialized:
Copy Code | |
---|---|
PIC_PARM pic_parm;
pic_parm.u.ParmSize = sizeof(PIC_PARM);
pic_parm.u.ParmVer = CURRENT_PARMVER;
pic_parm.u.ParmVerMinor = 2;
pic_parm.u.Op = OP_LIE3; |
It is recommended that a defer function callback is defined, assigned to DeferFn and F_UseDeferFn set in Flags. REQ_INIT returns the minimum size for the Put buffer in u.LL3.StripSize and image information in the u.LL3.Region structure. The Put queue must be at least u.LL3.StripSize bytes in length.
If u.LL3.AllowedBitErr were set when the image was compressed, then the value used for compression is returned to the application by OP_LIE3.
See UniversalCT and NumUC in LOSSLESS3:OP_LIE3 for a description of how lossless JPEG pixel gray levels or color intensities can be mapped to new values. This might be used to apply gamma correction to a grayscale image. If u.LL3.UniversalCT is not provided, and if the input precision is greater than the output DIB bits per pixel, then the input gray or color intensity levels are scaled to uniform output intensity levels as though a 256-element u.LL3.UniversalCT were provided and where the value of each element were the same as the 0-based index of the element. For example, if a 12-bit lossless JPEG grayscale image is expanded, the scaling function described in LOSSLESS3:OP_LIE3 is used to scale the 12-bit JPEG input pixel values to the 8-bit DIB output pixel values.
If PF_YieldPut is set in u.LL3.PicFlags then the RES_PUT_DATA_YIELD response is returned periodically during compression. This allows an application to progressively display the image being expanded, or to update expansion progress reporting.
Image parameters are returned in the u.LL3.Region structure after RES_DONE is returned from REQ_INIT. An application may adjust some of these parameters before calling REQ_EXEC to change the default output formatting of the decompressed image. If stride would exceed 32767, set ParmVerMinor to 4 so that u.LL3.Region is considered a REGION2 structure. Otherwise, ParmVerMinor should be set to 2 so that u.LL3.Region is considered a REGION structure. See the LOSSLESS3:OP_LIE3 section and the REGION2 section for more information.
Image file comments are returned using P2P_Comment packets and scripts using P2P_Script packets on the PIC2List. Any APP markers are returned in P2P_RawData packets with RawDescription “APPn” where n is the hexadecimal APP marker number. If PF_HaveWatermark is set u.LL3.PicFlags, an ASCIIZ watermark string was recovered from the image and returned as a P2P_Watermark packet. See include\pic2file.h and the PIC2List section of Accessing Comments and Other Auxiliary Data in the PICTools and AIMTools Programmer’s Guide for more information about PIC2List packets.
The following LOSSLESS3 fields may be recovered from the compressed image to assist applications with presentation of the decompressed image: NumOfPages, PageNum, DispMethod, UserDelay, XOff, YOff, and Transparent. For more information about these fields, see the LOSSLESS3:OP_LIE3 section.
This opcode allows decompressing an image previously compressed with PICTools and password protected. See details in the section describing the PIC_PARM KeyField field. |
An RGB lossless JPEG image (u.LL3.Region.PixType equals PT_RGB or PT_RGBM) with 3 components and 2-8bpc is decompressed to 24bpp RGB output. An input image with 3 components and 16bpc is decompressed to 48bpp RGB output.
If F_Raw is not set in Flags, then the output image rows are padded to a 32-bit boundary. Otherwise, set F_Raw in Flags and optionally modify u.LL3.Region.Stride and u.LL3.StripSize after REQ_INIT returns RES_DONE and before calling REQ_EXEC. Ensure the Put queue size is at least the new u.LL3.StripSize:
Copy Code | |
---|---|
pic_parm.u.LL3.StripSize = (pic_parm.u.LL3.StripSize / pic_parm.u.LL3.Region.Stride) * NewStride; pic_parm.u.LL3.Region.Stride = NewStride; |
By default, decompressed images use little-endian(Intel) byte order for storing each component. To use big-endian(Motorola) byte order, set u.LL3.Region.PixType to PT_RGBM.
By default, decompressed images use interleaved pixel samples ordered blue, green, and then red. To order samples red, green, and then blue, set RF_SwapRB in u.LL3.Region.Flags before calling REQ_EXEC.
Color intensity mapping is not available to input images with 3 components and 16bpc. Values provided to u.LL3.UniversalCT and u.LL3.NumUC for such images are ignored.
A color-mapped IMStar or LOCO image (u.LL3.Region.PixType equals PT_CM) is decompressed to an image with the same bit-depth as the original, as either a color-mapped or grayscale output.
If an image is color-mapped, Head.biClrUsed is set to the number of colors in the color map and ColorTable is populated with palette in the image. The ColorTable data is available after REQ_INIT for the application to use for reserving space in the output file. Set RF_MakeGray in u.LL3.Region.Flags to convert and apply the color map to its equivalent gray colors, resulting in a uniform grayscale output image.
If F_Raw is not set in Flags, then the output image rows are padded to a 32-bit boundary. If an image has 1 to 4 bits per pixel, two pixels are packed into each output byte.
Otherwise, set F_Raw in Flags and optionally modify u.LL3.Region.Stride and u.LL3.StripSize after REQ_INIT returns RES_DONE and before calling REQ_EXEC. Ensure the Put queue size is at least the new u.LL3.StripSize:
Copy Code | |
---|---|
pic_parm.u.LL3.StripSize = (pic_parm.u.LL3.StripSize / pic_parm.u.LL3.Region.Stride) * NewStride; pic_parm.u.LL3.Region.Stride = NewStride; |
Each pixel occupies one byte.
A grayscale lossless JPEG, IMStar, or LOCO image (u.LL3.Region.PixType equals PT_GRAY) is decompressed to a grayscale output with the same bit-depth as the original, or a specified bit depth when u.LL3.Region.Bpp is set to another value before REQ_EXEC.
If F_Raw is not set in Flags, then the output image rows are padded to a 32-bit boundary. If the input has 9 to 16 bits per pixel, then output will have 8 bits per pixel. If the output has 1 to 4 bits per pixel, two pixels are packed into each output byte.
Otherwise, set F_Raw in Flags and optionally modify u.LL3.Region.Stride and u.LL3.StripSize after REQ_INIT returns RES_DONE and before calling REQ_EXEC. Ensure the Put queue size is at least u.LL3.StripSize:
Copy Code | |
---|---|
pic_parm.u.LL3.StripSize = (pic_parm.u.LL3.StripSize / pic_parm.u.LL3.Region.Stride) * NewStride; pic_parm.u.LL3.Region.Stride = NewStride; |
If the output has 1 to 8 bits per pixel, each pixel will occupy one byte; if the output has 9 to 16 bits per pixel, each pixel will occupy two bytes.
If the output has 9 to 16 bits per pixel, set u.LL3.Region.PixType to PT_GRAYM before REQ_EXEC to decompress pixels to Motorola/big-endian format. Otherwise, if u.LL3.Region.PixType is PT_GRAY, the pixels are decompressed to Intel/little-endian format.
By default, an image compressed with a non-zero u.LL3.AllowedBitErr will be decompressed to the same bits per pixel as the original image but with the discarded bits set to 0. Alternatively, the image can be decompressed using fewer bits per pixel by decreasing u.LL3.AllowedBitErr. When u.LL3.Region.Bpp plus u.LL3.AllowedBitErr was originally 9 to 16 and becomes 8 or less after decreasing u.LL3.AllowedBitErr, then u.LL3.Region.Stride and u.LL3.StripSize will also need to be adjusted.
An incorrect compressor can create incorrect lossless JPEG images by neglecting to mask out-of-range bits for the image bit depth. However, if all other lossless JPEG computations are correct, the original image, including such incorrect out-of-range bits, can be losslessly recovered. If these out-of-range bits are discovered during decompression, a warning Status of ERR_BAD_PIXELBITS is returned along with the fully decoded image.
Considering that the “effective” compressed image bits per pixel equals u.LL3.NativeBpp minus u.LL3.AllowedBitErr, as returned from REQ_INIT, out-of-range bits may be returned if these conditions are met:
However, if the output bits per pixel, u.LL3.Region.Bpp, exceeds the effective compressed image bits per pixel, then some out-of-range bits might be shifted and thereby lost.
For 16bpp images, some non-Accusoft lossless JPEG compressors can create non-compliant lossless JPEG images due to a bug caused by their incorrect reading of the lossless JPEG specification. A compliant JPEG decompressor cannot decompress these images, but these non-compliant decompressors exactly reverse the non-compliant compression so they can view the images as expected. Their decompressor bug also means that these decompressors cannot decompress all compliant lossless JPEG 16bpp images such as are created by OP_LIP3.
There are so many of these non-compliant images in the field that Accusoft has implemented a decompressor work-around to allow these non-compliant images to be decompressed. Set PF_IgnoreBadSuffix in u.LL3.PicFlags to decompress an image known to be non-compliant. Be aware, however, that setting this flag for a compliant image may cause the image to be decompressed incorrectly.
It is impossible in principle for OP_LIE3, or any decompressor, to detect with absolute certainty whether a compressed image was created with a buggy compressor or by a compliant compressor. However, OP_LIE3 provides an Accusoft-proprietary method that, with high probability, will automatically detect whether the compressed image is compliant or not and then correctly decode it. OP_LIE3 does this when PF_AutoIgnoreBadSuffix is set in u.LL3.PicFlags. If non-compliant encoding of the image is detected, OP_LIE3 will set PF_IgnoreBadSuffix in u.LL3.PicFlags; if the image was found to be compliant, the flag will be cleared. In the unlikely case that OP_LIE3 cannot do an automatic detection and return without error or if OP_LIE3 returns without error but the decoded image appears wrong, do not set PF_AutoIgnoreBadSuffix but set or clear PF_IgnoreBadSuffix to explicitly force non-compliant or compliant decoding, respectively. If the error persists, then the image is bad.
Some non-Accusoft lossless JPEG compressors can create non-compliant lossless JPEG images due to a bug caused by their incorrect reading of the lossless JPEG specification: they insert zero bits to "pad" to a byte boundary instead of one bits. A compliant JPEG decompressor should reject these images, but these non-compliant decompressors exactly reverse their expectation for padding bits and accept the images as correct, or simply do not check for the correct padding bits, in which case corrupt images may go undetected.
Because there are so many of these non-compliant images in the field, Accusoft treats bad padding bits such that instead of returning RES_ERROR on such images, RES_DONE is returned together with a non-fatal warning status ERR_BAD_DATA. To suppress the warning status, when such images are likely, set the flag PF2_AllowBadPaddingBits in u.LL3.PicFlags2. The flag PF2_FoundBadPaddingBits is set in u.LL3.PicFlags2 when bad padding bits are detected, even when PF2_AllowBadPaddingBits is set.
Please note the following: