Generic YUV Conversion

Generic YUV conversion provides the ability to convert any YUV format to any supported color space, using the YUV_PARAMS structure and adhering to the restrictions listed below. After defining the YUV format, you can proceed with the conversion normally, just like any other conversion. Use LColor::Convert to perform the conversion and call LColor::Free to free the conversion object. Currently the conversion from any color space to Generic YUV is not supported.

Generic YUV conversion currently has the following restrictions:

1.

No sub-sampling of Y is supported

2.

The number of Y elements must be a multiple of both U, and V.

3.

With non-planar formats, vertical sub-sampling of Y, U, and V is not supported.

4.

No alignment supported in planar format; line width must not contain additional bytes.

5.

The horizontal sub-sampling periods of U, and V must be multiples of each other, and the vertical sub-sampling periods of U, and V must be multiples of each other.

Examples:

1.

Converting Y41P to RGB using Generic YUV Conversion:

L_VOID GenericY41PToRGB(L_UCHAR *pIn, L_UCHAR *pOut, L_INT nWidth, L_INT nHeight) 
{
   /*Declare an object*/
   LColor clr; 

   /*Declare a CONVERSION_PARAMS structure*/
   CONVERSION_PARAMS cpParams; 
   /*Declare a YUV_PARAMS structure*/
   YUV_PARAMS yuvParams; 

   /*Byte ordering of the format; for Y41P: 
   U0 Y0 V0 Y1 U4 Y2 V4 Y3 Y4 Y5 Y6 Y7
   0    1    2    3    4    5    6    7    8   9    10  11
   Put the Y component order first, then the U and V last as follows: 
   Y positions: 1,3,5,7,8,9,10,11
   U positions: 0,4
   V positions: 2,6   */

   L_INT pOff[] = {1,3,5,7,8,9,10,11,0,4,2,6}; 

   ZeroMemory (&cpParams, sizeof (CONVERSION_PARAMS)); 
   /*Determine the size of the structure*/
   yuvParams.uStructSize = sizeof(YUV_PARAMS); 
   /*Determine the horizontal sub-sampling of U */
   yuvParams.nUh = 4; 
   /*Determine the vertical sub-sampling of U */
   yuvParams.nUv = 1; 
   /*Determine the horizontal sub-sampling of V */
   yuvParams.nVh = 4; 
   /*Determine the vertical sub-sampling of V */
   yuvParams.nVv = 1; 
   /*Set the byte ordering*/
   yuvParams.pOffsets = pOff; 
   /*The YUV values range*/
   yuvParams.nRange = YUVRANGE_FULL; 
   /*This represents the macro pixels(smallest group of pixels allowed), which indicates how many actual pixels are in the macro pixel. This value is important only in non - planar format*/
   yuvParams.nMacroPixel = 8; 
   /*This is a Boolean value that represents the type of the YUV format (Planar = TRUE, or non - Planar = FALSE.)*/ 
   yuvParams.bPlanar =FALSE; 

   /*Fill the pYuvParams value with the address of the YUV_PARAMS structure*/
   cpParams.pYuvParams = &yuvParams; 
   /*Determine the size of CONVERSION_PARAMS*/
   cpParams.uStructSize = sizeof (CONVERSION_PARAMS); 
   /*Determine the type of conversion to be used in the conversion, for YUVGeneric, only use USE_BUILTIN*/
   cpParams.nMethod = USE_BUILTIN; 
   /*Determine the type of conversion to be activated. For YUVGeneric, 
   only USE_BUILTIN*/
   cpParams.nActiveMethod = USE_BUILTIN; 

   /*Initialize the conversion*/
   clr.Initialize (CCS_YUV, CCS_RGB, &cpParams); 

   /*Convert the buffers pIn to pOut*/
   clr.Convert (pIn, pOut, nWidth, nHeight, 0, 0); 

   /*Free the object*/
   clr.Free ();
}

 

2.

Converting YVU9 (Planar) to RGB using Generic YUV Conversion:

L_VOID GenericYVU9ToRGB(L_UCHAR *pIn, L_UCHAR *pOut, L_INT nWidth, L_INT nHeight) 
{
   /*Declare an object*/
   LColor clr; 

   /*Declare a CONVERSION_PARAMS structure*/
   CONVERSION_PARAMS cpParams; 

   /*Declare a YUV_PARAMS structure*/
   YUV_PARAMS yuvParams; 

   /*This array of integers specifies the byte order of the yuv format. For planar formats it takes only a single value that represents the plane sequence in the buffer: 
   YUV, YVU, UYV, UVY, VYU, or VUY.*/ 
   L_INT pOff[] = {PLANAR_YVU}; /*PLANAR_YVU means the Y plane comes first in the buffer, then the V plane, and the U plane is last*/

   ZeroMemory (&cpParams, sizeof (CONVERSION_PARAMS)); 

   /*Determine the size of the structure*/
   yuvParams.uStructSize = sizeof(YUV_PARAMS); 

   /*Determine the horizontal sub-sampling of U*/
   yuvParams.nUh = 4; 

   /*Determine the vertical sub-sampling of U*/
   yuvParams.nUv = 4; 

   /*Determine the horizontal sub-sampling of V*/
   yuvParams.nVh = 4; 

   /*Determine the vertical sub-sampling of V*/
   yuvParams.nVv = 4; 

   /*This is a pointer to an integer. Pass the byte order array.*/ 
   yuvParams.pOffsets = pOff; 

   /*The range value determines the YUV range values. */
   yuvParams.nRange = YUVRANGE_FULL; 

   /*This represents the macro pixels(smallest group of pixels allowed) , which indicates how many actual pixels are in the macro pixel. This value is important only in non - planar format*/
   yuvParams.nMacroPixel = 16; 

   /*This is a Boolean value that represents the type of the YUV format (Planar, or non - Planar.)*/ 
   yuvParams.bPlanar = TRUE; 

   /*Pass the YUV_PARAMS structure address to the pYuvParams member of the CONVERSION_PARAMS structure.*/ 
   cpParams.pYuvParams = &yuvParams; 

   /*Determine the size of the CONVERSION_PARAMS structure.*/ 
   cpParams.uStructSize = sizeof (CONVERSION_PARAMS); 

   /*Determine the type of conversion to be used. For YUVGeneric, use only USE_BUILTIN*/
   cpParams.nMethod = USE_BUILTIN; 

   /*Determine the type of conversion to be activated. For YUVGeneric, use only USE_BUILTIN.*/ 
   cpParams.nActiveMethod = USE_BUILTIN; 

   /*Initialize the conversion*/
   clr.Initialize (CCS_YUV, CCS_RGB, &cpParams); 

   /*Convert the buffers pIn to pOut*/
   clr.Convert (pIn, pOut, nWidth, nHeight, 0, 0); 

   /*Free the object*/
   clr.Free ();
}