changeset 4076:47b9d8d3f3c5

committed Tim Ferguson's patch for proper YUV color space conversion
author melanson
date Thu, 10 Jan 2002 05:58:49 +0000
parents 2d4422703753
children 62f672249df1
files cinepak.c
diffstat 1 files changed, 38 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/cinepak.c	Thu Jan 10 02:01:10 2002 +0000
+++ b/cinepak.c	Thu Jan 10 05:58:49 2002 +0000
@@ -43,6 +43,12 @@
 /* ------------------------------------------------------------------------ */
 static unsigned char *in_buffer, uiclip[1024], *uiclp = NULL;
 
+#define SCALEBITS 16
+#define ONE_HALF  ((long) 1 << (SCALEBITS-1))
+#define FIX(x)    ((long) ((x) * (1L<<SCALEBITS) + 0.5))
+static long CU_Y_tab[256], CV_Y_tab[256], CU_Cb_tab[256], CV_Cb_tab[256],
+	CU_Cr_tab[256], CV_Cr_tab[256];
+
 #define get_byte() *(in_buffer++)
 #define skip_byte() in_buffer++
 #define get_word() ((unsigned short)(in_buffer += 2, \
@@ -54,6 +60,8 @@
 /* ---------------------------------------------------------------------- */
 static inline void read_codebook_yuy2(cvid_codebook *c, int mode)
 {
+unsigned char y0, y1, y2, y3, u, v;
+int y_uv;
 
 	if(mode)		/* black and white */
 		{
@@ -65,12 +73,25 @@
 		}
 	else			/* colour */
 		{
-		c->y0 = get_byte();  /* luma */
-		c->y1 = get_byte();
-		c->y2 = get_byte();
-		c->y3 = get_byte();
-		c->u = 128+get_byte(); /* chroma */
-		c->v = 128+get_byte();
+		y0 = get_byte();  /* luma */
+		y1 = get_byte();
+		y2 = get_byte();
+		y3 = get_byte();
+		u = 128+get_byte(); /* chroma */
+		v = 128+get_byte();
+
+		/*             YUV * inv(CinYUV)
+		 *  | Y  |   | 1 -0.0655  0.0110 | | CY |
+		 *  | Cb | = | 0  1.1656 -0.0062 | | CU |
+		 *  | Cr |   | 0  0.0467  1.4187 | | CV |
+		 */
+		y_uv = (int)((CU_Y_tab[u] + CV_Y_tab[v]) >> SCALEBITS);
+		c->y0 = uiclp[y0 + y_uv];
+		c->y1 = uiclp[y1 + y_uv];
+		c->y2 = uiclp[y2 + y_uv];
+		c->y3 = uiclp[y3 + y_uv];
+		c->u = uiclp[(int)((CU_Cb_tab[u] + CV_Cb_tab[v]) >> SCALEBITS)];
+		c->v = uiclp[(int)((CU_Cr_tab[u] + CV_Cr_tab[v]) >> SCALEBITS)];
 		}
 }
 
@@ -324,7 +345,7 @@
 void *decode_cinepak_init(void)
 {
 cinepak_info *cvinfo;
-int i;
+int i, x;
 
 	if((cvinfo = calloc(sizeof(cinepak_info), 1)) == NULL) return NULL;
 	cvinfo->strip_num = 0;
@@ -336,6 +357,16 @@
 			uiclp[i] = (i < 0 ? 0 : (i > 255 ? 255 : i));
 		}
 
+	for(i = 0, x = -128; i < 256; i++, x++)
+		{
+		CU_Y_tab[i] = (-FIX(0.0655)) * x;
+		CV_Y_tab[i] = (FIX(0.0110)) * x + ONE_HALF;
+		CU_Cb_tab[i] = (FIX(1.1656)) * x;
+		CV_Cb_tab[i] = (-FIX(0.0062)) * x + ONE_HALF + FIX(128);
+		CU_Cr_tab[i] = (FIX(0.0467)) * x;
+		CV_Cr_tab[i] = (FIX(1.4187)) * x + ONE_HALF + FIX(128);
+		}
+
 	return (void *)cvinfo;
 }