From: madler@cco.caltech.edu (Mark Adler)
Subject: Re: MPEG decoder
Keywords: MPEG
Organization: California Institute of Technology, Pasadena
Date: Sat, 22 Aug 1992 05:24:25 GMT


ketan patel requests:
>> the proper matrix to use for
>> straight MPEG YCrCb -> RGB conversion? 

I have appended my "y2rmatrx.h" file, which contains (to the best of
my knowledge) the correct conversion matrix based on the standard
definition of the y, u, and v signals, and the CCIR-601 digitization
of those.

I also have programs that use the .h file (of course), and they can
be had for the asking.

Mark Adler
madler@tybalt.caltech.edu
---- y2rmatrx.h ----
/*
   y2rmatrx.h	Mark Adler	28 August 1991

   This file defines the constants y2rNS, y2rXY, y2rRV, y2rGU, y2rGV, and
   y2rBU.  The first is a shift factor, and the rest are components of the
   conversion matrix.  The comments below describe the meaning and
   derivation of those constants.
*/

/* The following constants are derived from the observed relative brightness
   of red, green, and blue to define luminance, Y = 0.299R + 0.587G + 0.114B.
   Then the color difference signals, B-Y and R-Y, are normalized to the
   range -0.5 to 0.5 (for R, G, and B in 0 to 1) to the signals U and V,
   respectively.  This RGB to YUV matrix is then inverted to give the YUV to
   RGB conversion matrix (here in its exact rational form):

	1	0		701/500
	1	-25251/73375	-209599/293500
	1	443/250		0

   This applies to the electrical signals.  The digital versions are
   scaled and shifted as follows (lower case is the digital form):

	y = 219*Y + 16		or	Y = (y - 16)/219
	u = 224*U + 128		or	U = (u - 128)/224
	v = 224*V + 128		or	V = (v - 128)/224

   Since we are converting for the purpose of display, we will use the
   entire range for eight bit RGB values and define:

        r = 256*R
	g = 256*G
	b = 256*B

   where the r, g, and b values are rounded down or clipped to the range
   of 0..255.  This breaks the interval [0,1] into 256 equal size pieces.
   Then 0 covers [0,1/256) and negative values, 1 covers [1/256,2/256),
   ..., and 255 covers [255/256,1] and values greater than one.

   We will offset the y, u, and v values first (to improve the accuracy
   of the calculation--we could just bring an overall constant in front
   instead), and then the transformation matrix becomes, in its exact
   rational form:
 
 	256/219		0		1402/875
	256/219		-202008/513625	-419198/513625
	256/219		1772/875	0

   This gives five non-zero constants (aside from the offsets) that
   define the conversion.  They are multiplied by a power of two and
   rounded for the integer calculation. */

/* The constants below correspond to the above matrix as follows:

	y2rXY		0		y2rRV
	y2rXY		y2rGU		y2rGV
	y2rXY		y2rBU		0

   where the whole matrix is multiplied by 2**(-y2rNS). */

/*
#define y2rNS 8
#define y2rXY 299
#define y2rRV 410
#define y2rGU (-101)
#define y2rGV (-209)
#define y2rBU 518
*/

#define y2rNS 12
#define y2rXY 4788
#define y2rRV 6563
#define y2rGU (-1611)
#define y2rGV (-3343)
#define y2rBU 8295

/*
#define y2rNS 16
#define y2rXY 76608L
#define y2rRV 105007L
#define y2rGU (-25775L)
#define y2rGV (-53488L)
#define y2rBU 132720L

#define y2rNS 22
#define y2rXY 4902931L
#define y2rRV 6720473L
#define y2rGU (-1649614L)
#define y2rGV (-3423205L)
#define y2rBU 8494065L
*/
Newsgroups: comp.compression.research