Send comments on this topic. | Back to Introduction - All Topics | Help Version 16.5.9.25
LEAD Bitmap Encoder Property Bag: Jpeg2000 Specific Options
See Also

Provides additional options for the LEAD Jpeg2000 Bitmap Encoder.

Property Bag Items

LEAD Jpeg2000 Encoder Options
Property Name VARTYPE Default Value Applicable LEAD Encoders Description
J2k_UseColorTransform VT_BOOL VARIANT_TRUE Jpeg2000

Flag that indicates whether to convert an RGB image to YUV space before compressing. YUV provides greater compression with higher image quality.

TRUE: Convert to YUV space before compressing. (Default)

FALSE: Do not convert to YUV space before compressing

J2k_DerivedQuantization VT_BOOL VARIANT_TRUE Jpeg2000 Flag that indicates whether to use derived quantization or expounded quantization, which determines quality and speed.

TRUE: Use derived quantization.

FALSE: Use expounded quantization.
J2k_CompressionControl VT_I WICLeadJ2kCompressionControl
Default is WICLeadJ2kCompressionQualityFactor
Jpeg2000
cmw
tiff (subformat WICLeadSubFormatTifCmw)
See WICLeadJ2kCompressionControl
J2k_CompressionRatio VT_R4 1 Jpeg2000, cmw Indicates the compression ratio to use if J2k_CompressionControl is WICLeadJ2kCompressionRatio.
J2k_TargetFileSize VT_I4 0 Jpeg2000, cmw Target file size in bytes if J2k_CompressionControl is WICLeadJ2kCompressionTargetSize.
J2k_HorizontalOffset VT_UI4 0 Jpeg2000

Horizontal offset from the origin of the reference grid to the left side of the image area, in pixels.

J2k_VerticalOffset VT_UI4 0 Jpeg2000

Vertical offset from the origin of the reference grid to the top of the image area, in pixels.

J2k_TileWidth VT_UI4 640 Jpeg2000 Width of one reference tile, with respect to the reference grid, in pixels.
J2k_TileHeight VT_UI4 480 Jpeg2000 Height of one reference tile, with respect to the reference grid, in pixels.
J2k_TileHorizontalOffset VT_UI4 0 Jpeg2000

Horizontal offset from the origin of the reference grid to the left side of the first tile, in pixels.

J2k_TileVerticalOffset VT_UI4 0 Jpeg2000

Vertical offset from the origin of the reference grid to the top of the first tile, in pixels.

J2k_DecompressLevel VT_UI4 5 Jpeg2000

Number of resolution levels in the compressed file. The maximum number of levels depends on the size of the image. Passing values that are too large will cause the save operation to fail. Each resolution level is one-half the size of the previous resolution,  in both dimensions (width and height), starting with the full image resolution. The resolutions are not stored independently, and do not have a major impact on the compression results. The default value is 5, which produces the best compression ratios in most cases.

J2k_ProgressOrder VT_UI4 WICLeadJ2kProgressOrder
Default is WICLeadJ2kProgressLayerResolutionComponentPosition
Jpeg2000, cmw For more information, refer to WICLeadJ2kProgressOrder
J2k_CodeBlockWidth VT_I4 64 Jpeg2000

Width of the code block, following wavelet transformation. The value must be a power of 2. It must be at least 4 and less than or equal to 1024.

J2k_CodeBlockHeight VT_I4 64 Jpeg2000

Height of the code block, following wavelet transformation. The value must be a power of 2. It must be at least 4 and less than or equal to 1024.

J2k_SelectiveACBypass VT_BOOL VARIANT_FALSE Jpeg2000 TRUE if the "lazy coding mode" is adopted. In this case, trailing bit-planes bypass the arithmetic coder except in the normalization pass. Otherwise, the arithmetic coder is used on all passes.
J2k_ResetContextOnBoundaries VT_BOOL VARIANT_FALSE Jpeg2000

TRUE if the arithmetic coder's probability models are reset between coding passes. This controls where the end of encoded data is and limits the amount of potentially lost data in the event of a transmission error.

J2k_TerminationOnEachPass VT_BOOL VARIANT_FALSE Jpeg2000

TRUE if the arithmetic code-word generation process stops on a byte boundary at the end of each coding pass.

J2k_VerticallyCausalContext VT_BOOL VARIANT_FALSE Jpeg2000

TRUE if the context models are restricted to being vertically causal within each sub-block.

J2k_PredictableTermination VT_BOOL VARIANT_FALSE Jpeg2000

TRUE if the encoder has a predictable termination policy and identifies that the policy was used in the code-stream COD/COC markers. This can be used to implement error detection and concealment.

J2k_ErrorResilienceSymbol VT_BOOL VARIANT_FALSE Jpeg2000

TRUE if a 4-symbol marker is included for each bit-plane, following the normalization pass.

J2k_GuardBits VT_UI4 2 Jpeg2000

Additional most significant bits that have been added to sample data (number of extra bits to consider when encoding an image). This prevents coding overflow. Possible values are 0 - 7. The default is 2. A value of 2 or 1 will produce the best compression.

J2k_DerivedBaseMantissa VT_I4 0 Jpeg2000

The base mantissa used for derived quantization.

J2k_DerivedBaseExponent VT_I4 8 Jpeg2000

The base exponent used for derived quantization.

J2k_UseSOPMarker VT_BOOL VARIANT_FALSE Jpeg2000 TRUE: Use the SOP marker. If TRUE, each packet in any given tile part will be prepended with an SOP marker segment. The SOP marker includes the size of the packet.

FALSE: Do not use the SOP marker. (Default)
J2k_UseEPHMarker VT_BOOL VARIANT_FALSE Jpeg2000 TRUE: Each packet header in any given tile part is postpended with an EPH marker segment

FALSE: Do not use the EPH marker. (Default)
J2k_UseROI VT_BOOL VARIANT_FALSE Jpeg2000 TRUE: Use a region of interest as specified with J2k_ROILeft, J2k_ROITop, J2k_ROIRight, J2k_ROIBottom
J2k_ROILeft VT_I4 0 Jpeg2000 Left boundary of the region of interest, in pixels.
J2k_ROITop VT_I4 0 Jpeg2000 Top boundary of the region of interest, in pixels.
J2k_ROIRight VT_I4 0 Jpeg2000 Right boundary of the region of interest, in pixels.
J2k_ROIBottom VT_I4 0 Jpeg2000 Bottom boundary of the region of interest, in pixels.
J2k_AlphaChannelLossless VT_BOOL VARIANT_FALSE Jpeg2000 TRUE: Save with a lossless alpha channel

FALSE: Save without a lossless alpha channel.
J2k_AlphaChannelActiveBits VT_UI4 8 Jpeg2000 1: The 256 levels of the 8-bit alpha channels will be transformed into two levels of value 255 or 0, using simple thresholding. The threshold value is 127, so all values > 127 will be set to 255 and all values <= 127 will be set to 0.
If the alpha channel is set as a bi-level image, the result will be a better compression ratio.

8: All 256 levels of the 8-bit alpha channels will be compressed.

 

Comments

The JPEG2000 image format offers both superior compression performance and robust file handling. Some J2K options can have a direct impact on compression performance, while others primarily affect the resulting file size. Notes on Advanced options continue below.

Main options (listed above) include:

  • Color Transforms

  • Compression Settings

  • Multiple resolution representation (Wavelet Decomposition Level)

  • Random codestream access and processing (Progression Order)

  • Progressive transmission (Advanced)

  • Tile Size

  • Error resilience for transmission in noisy environments, such as wireless and the Internet.

  • Region-of-Interest coding.

Controlling File Size and Compression Ratio

The following properties affect the file size and the compression ratio.

J2k_CompressionControl

J2k_CompressionRatio

J2k_TargetFileSize

J2k_ProgressOrder

The resulting file size/ compression ratio can be determined in several ways. Depending on the value set in the J2k_CompressionControl member, the user can set the size of the target file, the actual compression ratio used during compression or the quality factor used during compression. If J2k_CompressionControl is set to WICLeadJ2kCompressionRatio, then the compression used is based on the compression ratio in the J2k_CompressionRatio property. If J2k_CompressionControl is set to WICLeadJ2kCompressionTargetSize, the compression used is based on the desired target file size in the J2k_TargetFileSize property. If J2k_CompressionControl is set to WICLeadJ2kCompressionQualityFactor, then the compression used is based on the QualityFactor property.

Lossless Compression

For lossless compression, set the J2k_CompressionControl to WICLeadJ2kCompressionLossless.

Lossy Compression Quantization

There are two types of quantization for Lossy compression: Scalar Derived Quantization and Scalar Expounded Quantization.

The exponent/mantissa pairs are either signaled in the codestream for every sub-band (expounded quantization) or else signaled only for the Low Pass sub-band and derived for all other sub-bands (derived quantization). In the case of derived quantization, all exponent/mantissa pairs are derived from the single exponent/mantissa pair corresponding to the Low pass sub-band.

 The quantization step size for a sub-band is calculated from the dynamic range of the sub-band using the following equation, where R = bpp for the sub-band:

Quantization Step = (2 (R - Exponent) ) * [1 + (Mantissa / 2048)]

If the value of  J2k_CompressionControl is WICLeadJ2kCompressionRatio, WICLeadJ2kCompressionQualityFactor or WICLeadJ2kCompressionTargetSize, and the value of J2k_AlphaChannelLossless is TRUE, the compressed J2K/JP2 file will have three lossy components (red, green and blue) in addition to the lossless alpha component.

If the value of J2k)CompressionControl is WICLeadJ2kCompressionLossless, the value of J2k_AlphaChannelLossless will be ignored and all the components will be lossless.

Tile and Canvas Settings

The values of the J2k_HorizontalOffset, J2k_VerticalOffset, J2k_TileWidth, J2k_TileHeight, J2k_TileHorizontalOffset and J2k_TileVerticalOffset properties are used to create tiles within the image. Arbitrary tile sizes are allowed. All tiles are the same size, except for the border tiles. Each tile can be compressed individually. This can decrease memory usage while the program is running, but can also generate artifacts at the edges of the tiles. Artifacts generally increase as the size of the tile decreases. By default, there is one tile that contains the entire image.

The various parameters defining the reference grid appear in the figures below.

The reference grid is a rectangular grid of points with the indices from (0, 0) to (Xsiz-1, Ysiz-1). An �image area� is defined on the reference grid by the dimensional parameters, (Xsiz, Ysiz) and (J2k_HorizontalOffset, J2k_VerticalOffset).

Specifically, the image area on the reference grid is defined by its upper left hand reference grid point at location (J2k_HorizontalOffset, J2k_VerticalOffset), and its lower right hand reference grid point at location (Xsiz-1, Ysiz-1).

Progression Order

For a given tile-part, the packets contain all compressed image data from a specific layer, a specific component, a specific resolution level, and a specific precinct. The order in which these packets are found in the codestream is called the progression order. The ordering of the packets can progress along four axes: layer, component, resolution and position.

1. LAYER-RESOLUTION -COMPONENT-POSITION

A progression of this type might be useful when low sample accuracy is most desirable, but information is needed for all components.

2. RESOLUTION -LAYER-COMPONENT-POSITION

A progression of this type might be useful in providing low-resolution level versions of all image components.

3. RESOLUTION -POSITION-COMPONENT-LAYER

To use this progression, XRsiz and YRsiz values must be powers of two for each component. A progression of this type might be useful in providing low-resolution level versions of all image components at a particular spatial location.

4. POSITION-COMPONENT-RESOLUTION -LAYER

A progression of this type might be useful in providing high sample accuracy for a particular spatial location in all components.

5. COMPONENT-POSITION-RESOLUTION -LAYER

A progression of this type might be useful in providing high accuracy for a particular spatial location in a particular image component.

 

For More Information, Refer To:

ISO/IEC JTC1/SC29/WG1 N1861: Coding of Still Pictures

See Also

Example

// ******************************************************************************************************************
// This example shows how to save a Jpeg2000 file with options using the property bag
// Then the file is saved with the following options:
// * Subformat WICLeadSubFormatJp2
// * Target file size of 1024 bytes
// * Progressing Order -- color axis
// Refer to the Example Requirements for help in running this sample
HRESULT IWICLeadBitmapEncoder_PropertyBag_J2k(HWND hWnd, WCHAR *pszOut)
{
   HRESULT hr = S_OK;
   IWICImagingFactory *piImagingFactory = NULL;
   IWICBitmapEncoder *piBitmapEncoder = NULL;
   IWICBitmapFrameEncode *piBitmapFrameEncode = NULL;
   IWICStream *piStream = NULL;
   IPropertyBag2 *piPropertyBag = NULL;
   CString csExampleName;
   GUID guidContainerFormat = GUID_ContainerFormatLeadJ2k;
   WICPixelFormatGUID guidPixelFormat = GUID_WICPixelFormat24bppBGR;

   csExampleName.Format(L"IWICLeadBitmapEncoder_PropertyBag_J2k\nThis example creates a Jpeg2000 file (%s) with SubFormat WICLeadSubFormatJp2, Target size of 1024 bytes, and Progress order of Color Axis", pszOut);

   // Create a LEAD Jpeg Bitmap Encoder
   IFS(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*) &piImagingFactory));

   IFS(piImagingFactory->CreateStream(&piStream));
   IFS(piStream->InitializeFromFilename(pszOut, GENERIC_WRITE));
   IFS(piImagingFactory->CreateEncoder(guidContainerFormat, NULL, &piBitmapEncoder));
   IFS(piBitmapEncoder->Initialize(piStream, WICBitmapEncoderNoCache));
   IFS(piBitmapEncoder->CreateNewFrame(&piBitmapFrameEncode, &piPropertyBag));

   // This is how you customize the a LEAD WIC Encoder property bag.
   if(SUCCEEDED(hr))
   {        
      ULONG uCount = 0;
      hr = piPropertyBag->CountProperties(&uCount);
      PROPBAG2 *pBag = new PROPBAG2[uCount];
      ZeroMemory(pBag, sizeof(*pBag));

      VARIANT *pValue = new VARIANT[uCount];
      ZeroMemory(pValue, sizeof(*pValue));

      HRESULT *pErrors = new HRESULT[uCount];
      ZeroMemory(pErrors, sizeof(*pErrors));

      IFS(piPropertyBag->GetPropertyInfo(0, uCount, pBag, &uCount));
      IFS(piPropertyBag->Read(uCount, pBag, NULL, pValue, pErrors));
      if (SUCCEEDED(hr))
      {
         for (ULONG u = 0; u < uCount; u++)
         {
            if (wcscmp(pBag[u].pstrName, L"J2kSubFormat")== 0)
            {
               pValue[u].intVal = WICLeadSubFormatJp2;
               piPropertyBag->Write(1, pBag+u, pValue+u);
            }
            else if (wcscmp(pBag[u].pstrName, L"J2k_CompressionControl")== 0)
            {
               pValue[u].intVal = WICLeadJ2kCompressionTargetSize;
               piPropertyBag->Write(1, pBag+u, pValue+u);
            }
            else if (wcscmp(pBag[u].pstrName, L"J2k_TargetFileSize")== 0)
            {
               pValue[u].intVal = 1024;
               piPropertyBag->Write(1, pBag+u, pValue+u);
            }

            else if (wcscmp(pBag[u].pstrName, L"J2k_ProgressOrder")== 0)
            {
               pValue[u].uintVal = WICLeadJ2kProgressComponentPositionResolutionLayer;
               piPropertyBag->Write(1, pBag+u, pValue+u);
            }
         }
      }
      //Cleanup
      DELETE_POINTER(pBag);
      DELETE_POINTER(pValue);
      DELETE_POINTER(pErrors);

      IFS(piBitmapFrameEncode->Initialize(piPropertyBag));
   }

   // Now create the image data that we will write
   UINT uiWidth = 256;
   UINT uiHeight = 256;
   IFS(piBitmapFrameEncode->SetSize(uiWidth, uiHeight));
   WICPixelFormatGUID formatGUID = GUID_WICPixelFormat24bppBGR;
   IFS(piBitmapFrameEncode->SetPixelFormat(&formatGUID));

   if (SUCCEEDED(hr))
   {
      // We're expecting to write out 24bppRGB. Fail if the encoder cannot do it.
      hr = IsEqualGUID(formatGUID, GUID_WICPixelFormat24bppBGR) ? S_OK : E_FAIL;
   }

   if (SUCCEEDED(hr))
   {
      UINT cbStride = (uiWidth * 24 + 7)/8;
      UINT cbBufferSize = uiHeight * cbStride;
      BYTE *pbBuffer = new BYTE[cbBufferSize];

      if (pbBuffer != NULL)
      {
         for (UINT i = 0; i < cbBufferSize; i++)
         {
            pbBuffer[i] = static_cast<BYTE>(rand());
         }
         hr = piBitmapFrameEncode->WritePixels(uiHeight, cbStride, cbBufferSize, pbBuffer);
         delete[] pbBuffer;
      }
      else
      {
         hr = E_OUTOFMEMORY;
      }
   }

   // Commit the changes to the stream
   IFS(piBitmapFrameEncode->Commit());   
   IFS(piBitmapEncoder->Commit());

   RELEASE_INTERFACE(piBitmapFrameEncode);
   RELEASE_INTERFACE(piBitmapEncoder);
   RELEASE_INTERFACE(piImagingFactory);
   RELEASE_INTERFACE(piPropertyBag);
   RELEASE_INTERFACE(piStream);

   MessageBox(hWnd, csExampleName, csExampleName, MB_OK);
   return hr;
}