Operations > OP_J2KE, OP_J2KE3D, OP_J2KERGB |
OP_J2KE, OP_J2KE3D, OP_J2KERGB : Decompress JPEG2000
See the J2K_UNION, TILECOMP, TILE, PARTITION, REGION, REGION2 sections for additional information.
JPEG2000 decompression may be used to decompress images with varying grayscale and color bit-depths. Decompression options include thumbnail sizes, resolution detail, and progressive stages.
The input JPEG2000 compressed image can be in the JPEG2000 raw codestream format or in the JPEG2000 file format. The former is an excerpt of the latter.
The output decompressed image can be formatted as a Windows DIB with each row padded to a 32-bit boundary or as raw image data formatted as specified by the Region parameters. The decompression process performs no color reduction or other reformatting of the compressed data. Partitions are decompressed to separate Put buffers for reconstruction by the application.
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 is allocated and the basic structure members are initialized (PicParm.ParmSize = sizeof(PIC_PARM), PicParm.ParmVer = CURRENT_PARMVER, PicParm.ParmVerMinor = 3, PicParm.Op = OP_J2KE). It is recommended that a DeferFn function be defined and F_UseDeferFn be OR'ed into PicParm.Flags. REQ_INIT will return the minimum size for the Put buffer in u.J2K.StripSize. REQ_INIT will also return image information in the u.J2K.Region structure.
In order to support larger images, this opcode supports the optional use of REGION2. If ParmVerMinor is set to 4, then the opcode treats u.J2K.Region as a REGION2 structure instead of a REGION structure. Otherwise, ParmVerMinor should be set to 3. See the REGION2 section for more information.
For even larger images or other situations where memory is a concern, this opcode offers a reduced-memory mode of operation. More details of this mode can be found in the Reduced-Memory Mode section below.
The application allocates a Put buffer according to StripSize and the REQ_EXEC phase fills the Put buffer with decompressed image data.
If PF_YieldPut is set in u.J2K.PicFlags then OP_J2KE will return a RES_PUT_DATA_YIELD response periodically during decompression. This would allow an application to progressively display the image being expanded, or to update expansion progress reporting.
OP_J2KE returns image file comments using PIC2List P2P_Comment packets. JPEG 2000 errors or warnings returned from the underlying JPEG 2000 library optionally return additional descriptive text in PIC2List if there is enough space or if the application reacts to RES_EXTEND_PIC2LIST responses. In that case, ERR_PIC2LIST_HAS_DESCRIPTION is returned in Status and the information about the error appears in P2PktErrorText packets with Type P2P_ErrorText. 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.
If an image has:
then the image is decompressed as a 24-bit interleaved RGB image. If the file is a JP2 file format, then the color space must be RGB, and the first three components must not be remapped, i.e., they must be ordered red, green, and then blue in the compressed file.
When a reversible color transform is absent, PICTools does not assume that the components should be returned interleaved and as RGB, but rather returns the components as planar without assuming anything about the colorspace. To return interleaved RGB given a J2K file that contains three, unsigned 8-bpp components without a reversible color transform, set the PF2_J2K_TCTNone_RGB flag in J2K.PicFlags2.
If F_Bmp is set in PicParm.Flags, then the output image rows are padded to a 32-bit (DWORD) boundary, the output image is bottom up and the output interleaved RGB pixels' samples are ordered blue, green, and then red. Otherwise, set F_Raw in PicParm.Flags, and set RF_SwapRB and RF_TopDown in u.J2K.Region.Flags if desired. Set RF_SwapRB before REQ_EXEC, and OP_J2KE decompresses to interleaved pixels with samples ordered red, green, and then blue. Otherwise the decompressed interleaved pixels' samples are ordered blue, green, and then red.
If F_Raw is set, set Region.Stride if desired after RES_DONE is returned from REQ_INIT and before calling REQ_EXEC. If set, be sure to adjust StripSize to correspond and make sure the Put queue size is at least as big as the adjusted StripSize as:
StripSize= ( StripSize / Region.Stride ) * <NewStride>;
Region.Stride= <NewStride>;
If an image's first component:
then the image can be decompressed as a color-mapped image. Packed pixel output (more than one pixel per byte) is not supported. OP_J2KE sets PicParm.Head.biClrUsed to the number of colors in the color map and sets PicParm.ColorTable according to the colors in the color map as read from the pallette in the JPEG2000 image. PicParm.ColorTable is available after REQ_INIT for the application to use for reserving space in the output file but may change during REQ_EXEC to satisfy the setting of RF_SwapRB in u.J2K.Region.Flags evaluated during REQ_EXEC, in which case the application should rewrite the PicParm.ColorTable after the return from REQ_EXEC.
If F_Bmp is set in PicParm.Flags, then the output image rows are padded to a 32-bit (DWORD) boundary and the output image is bottom up. Otherwise, set F_Raw in PicParm.Flags and set RF_TopDown in u.J2K.Region.Flags if desired.
If F_Raw is set, set Region.Stride if desired after RES_DONE is returned from REQ_INIT and before calling REQ_EXEC. If set, be sure to adjust StripSize to correspond and make sure the Put queue size is at least as big as the adjusted StripSize as:
StripSize= ( StripSize / Region.Stride ) * <NewStride>;
Region.Stride= <NewStride>;
Set RF_MakeGray in u.J2K.Region.Flags to convert the color map to the equivalent gray colors and apply that gray color map to the color indices to result in a uniform grayscale output image.
Set RF_CM2RGB in u.J2K.Region.Flags to apply the color map to the color indices to result in a 24-bit RGB output image or 8-bit uniform gray output image depending on whether all color map colors are gray. If some color map color is not gray, set RF_SwapRB in u.J2K.Region.Flags before REQ_EXEC to decompress to interleaved RGB samples ordered red, green, and then blue. Otherwise the output interleaved RGB samples are ordered blue, green, and then red. Set PF2_KeepColorTable in u.J2K.PicFlags2 to optionally have OP_J2KE return the color map in PicParm.ColorTable that it would otherwise not return when RF_CM2RGB is set. Any returned color map colors are ordered according to RF_SwapRB.
It is generally not possible to decompress a palletized image to a thumbnail size by setting u.J2K.Thumbnail or to lower resolution by setting u.J2K.ExpandResolutionor u.J2K.ExpandLayers, because doing so will modify the indices and not the color palette, and such modified indices may no longer map to appropriate colors. |
If the above conditions aren't met for decompressing to an RGB or color-mapped image, and the component bits per sample is no more than 8-bits per sample, then it is decompressed to a grayscale component. Packed pixel output (more than one pixel per byte) is not supported.
If F_Bmp is set in PicParm.Flags, then the output image rows are padded to a 32-bit (DWORD) boundary, the output image is bottom up and the output image samples are unsigned, 8-bits-per-sample and one-byte-per-sample. Otherwise, set F_Raw in PicParm.Flags and set RF_TopDown, RF_2Byte (and optionally RF_BigEndian) and RF_Signed in u.J2K.Region.Flags if desired.
If F_Raw is set, set Region.Stride if desired after RES_DONE is returned from REQ_INIT and before calling REQ_EXEC. If set, be sure to adjust StripSize to correspond and make sure the Put queue size is at least as big as the adjusted StripSize as:
StripSize= ( StripSize / Region.Stride ) * <NewStride>;
Region.Stride= <NewStride>;
If the component samples are larger than 8-bits per sample, then the component is decompressed to high-gray samples.
Set F_Raw in PicParm.Flags and set RF_TopDown, RF_BigEndian, and RF_Signed in u.J2K.Region.Flags if desired.
If F_Raw is set, set Region.Stride if desired after RES_DONE is returned from REQ_INIT and before calling REQ_EXEC. If set, be sure to adjust StripSize to correspond and make sure the Put queue size is at least as big as the adjusted StripSize as:
StripSize= ( StripSize / Region.Stride ) * <NewStride>;
Region.Stride= <NewStride>;
The u.J2K.Region fields describe the first component, or first three components if RGB, of an image. For more complicated images, the application can allocate an array of PARTITION data structures to be filled in by OP_J2KE. Each element of the array describes a single partition. The first PARTITION, partition number 0, is specified by u.J2K.Region, u.J2K.StripSize and PicParm.Put. Partitions number 1 through u.J2K.NumOtherPartitions - 1, each describe a single other component after the component(s) described as partition 0. Partition number 1 is described by u.J2K.OtherPartitions[0], etc.
In the general case, the application won't know how many partitions to allocate for an input image before REQ_INIT. After RES_DONE is returned from REQ_INIT, OP_J2KE will return the total number of partitions in u.J2K.NumPartitions. Then, if desired, the application can call REQ_TERM to prematurely terminate OP_J2KE so the correct number of OtherPartitions can be allocated by the application. Now the application can start OP_J2KE over again with REQ_INIT and with the correct number of OtherPartitions. If there are fewer OtherPartitions than needed by the image, then the extra image components aren't decompressed.
When the Put queue is full and more output data for partition 0 is ready, a RES_PUT_NEED_SPACE response is returned, u.J2K.PartitionNum will be 0, and the new data will be returned in the PicParm.Put queue after it is emptied by the application. When a partition N queue is full and more output data is ready for that partition, a RES_PUT_NEED_SPACE response is returned, u.J2K.PartitionNum will be N, and the new data will be returned in the u.J2K.OtherPartitions[N].Queue queue after it is emptied by the application. Each u.J2K.OtherPartitions[N].Queue must be at least u.J2K.OtherPartitions[N].StripSize bytes in size.
If an image component is subsampled by horizontally or vertically by 8:1 or less, then the subsampling factor is returned in u.J2K.OtherPartitions[N].Region.Interlace. Otherwise, the subsampling factors can be determined using the combination of u.J2K.ImageXOff, u.J2K.ImageYOff, u.J2K.OtherPartitions[N].Region.Width and u.J2K.OtherPartitions[N].Region.Height. If PF2_SkipUpsampling is not set, OP_J2KE will return an upsampled version of the component by linearly interpolating intermediate samples. Otherwise, if PF2_SkipUpsampling is set, OP_J2KE will return the subsampled version of the component directly.
The image can be decompressed to a thumbnail size by setting u.J2K.Thumbnail to a value other than 0. The decompressed image height and width will be divided by 2u.J2K.Thumbnail and processing time and memory requirements are reduced by very roughly the same order. The returned Region.Width and Region.Height values will reflect the Thumbnail dimensions. The returned ImageWidth and ImageHeight will reflect the dimensions of the full-size image.
A JPEG2000 compressed image can be rendered with lower visual resolution and more quickly by skipping wavelet levels and/or quality layers when decompressing. Set u.J2K.ExpandResolution to the number of wavelet levels to skip. Set u.J2K.ExpandLayers to the number of quality layers to skip. The maximum number of levels or layers that will be skipped is limited to one less than the number of levels or layers, respectively, in the image.
A subrectangle of the input image can be compressed by setting F_Crop in PicParm.Flags and setting PicParm.CropXoff, PicParm.CropYoff, PicParm.CropWidth, and PicParm.CropHeight to describe the subrectangle. PicParm.CropXoff and PicParm.CropYoff are offsets within the image and not within the canvas. Processing time and memory requirements are reduced by very roughly the same proportion as the area of the subrectangle compared to the area of the image.
For Progressive decompression, the Q_EOF flag is used to specify that the compressed image data in the current Get queue is all the image data currently available. In this case, REQ_EXEC returns RES_DONE and the application uses REQ_TERM to end the decompression process. Then as more data is available in the Get queue, the REQ_INIT/REQ_EXEC/REQ_TERM process is rerun.
The opcode provides a means to drastically reduce the amount of memory required for decoding, thereby making it possible to decode extremely large images and/or operate where memory is otherwise limited. To use this mode, set the PF2_ReducedMemoryMode flag in u.J2K.PicFlags2 before REQ_INIT. The application then has the additional choice of whether to support seeking in the input stream or not by appropriately setting the PF2_UseResSeek flag or not in u.J2K.PicFlags2. Leaving the flag clear will typically use less memory and therefore is the recommended mode of operation for most images. For best performance, the image being decoded should contain only one layer, the PCRL progression order, and small precincts (128x128 recommended).
If the image had been compressed with more than one tile, then the reduced-memory mode requires that the opcode be able to seek in the input stream. The application must signal its ability to seek by setting the PF2_UseResSeek flag in u.J2K.PicFlags2 at REQ_INIT and/or REQ_EXEC. If it does not set the flag before REQ_INIT, the application can check for the existence of tiles by looking at the image and tile dimensions and offsets returned by REQ_INIT and then set the PF2_UseResSeek flag before the call to REQ_EXEC. Note that if the application sets this flag at REQ_INIT, then it must remain set at REQ_EXEC.
If seeking is enabled, be sure to use the values in the PicParm.SeekOffsetLow and PicParm SeekOffsetHigh fields when responding to a RES_SEEK request from the opcode in order to get the correct seek offset for extremely large images. If seeking is enabled in reduced-memory mode, multithreading within the opcode is not possible and the opcode operates in single-threaded mode irrespective of the value in PicParm.NumberOfThreadsAllowed.
If the JPEG2000 image is recognized as a 3D slice encoding of volumetric data, the opcode sets PF2_3D_Slices in u.J2K.PicFlags2 and expands the image as one slice per partition. Each partition carries data for one slice and can contain interleaved RGB samples (8 bits per sample; 24 bpp) or grayscale samples (up to 16 bits). Color-mapped images are not allowed. Subsampling is not allowed.
Set u.J2K.SliceOff before REQ_INIT to the offset of the first slice to expand; the first slice in the image (offset 0) is the default. The number of slices returned is the lesser of the number of partitions provided to the opcode at REQ_INIT or the number of slices in the image. The actual number of slices in the encoded image is returned by REQ_INIT in u.J2K.NumPartitions for the application to use in later invocations as needed.
The input JPEG2000 compressed image can be in the JPEG2000 raw codestream format or in the JPEG2000 JPX file format.
The opcode finds the most appropriate Color Specification Box for the image and if that box contains ICC Profile data, the data will be returned in u.J2K.ColorSpecICCProfileData and its length in u.J2K.ColorSpecICCProfileLen after REQ_INIT. Otherwise, the opcode returns the Part-1 enumerated colorspace if it finds one in the Color Specification Box. The memory pointed to by u.J2K.ColorSpecICCProfileData will be freed by the opcode during REQ_EXEC. The ICC Profile data will NOT be used when decoding the image.
If the JPEG2000 image contains Resolution Boxes, either Capture Resolution or Display Resolution, and you supply a J2K_EXTRA structure at PIC_PARM.opcodeExtraPtr, then the Horizontal and Vertical resolution values will be returned in opcodeExtraPtr->CaptureResVert, opcodeExtraPtr->CaptureResHorz, or opcodeExtraPtr->DisplayResVert, opcodeExtraPtr->DisplayResHorz.
If the JPEG2000 file contains UUID Boxes, UUID Info Boxes or XML Boxes then they will be returned on the PIC2List after REQ_INIT.
If the opcode knows how to parse a specific UUID Box then the UUID Box will not be on the PIC2List but the individual items will be. For instance, the opcode understands IPTC data and if the JPEG2000 file contains a UUID Box with UUID 33c7a4d2-b81d-4723-a0ba-f1a3e097ad38 then the UUID Box will be parsed and IPTC Packets will be returned on the PIC2List.
UUID Info Boxes will be broken into P2PktUUIDDataEntryURL packets for each UUID in the UUID Info Box.
XML Boxes can be UTF-8 or UTF-16. They will always be NULL terminated. If it is UTF-16 it will start with a Byte Order Marker (BOM) and be doubly NULL terminated.