From b2866b12d2a4dd47c8c6c7c342f9996bd27dc7ef Mon Sep 17 00:00:00 2001 From: iovar Date: Tue, 16 Sep 2008 17:04:11 +0000 Subject: src/rmd_yuv_utils.c : Applied patch by Luca Bonavita, that corrects the rgb to yuv algorithm and provides near perfect colorspace conversion. src/rmd_get_frame.c : The sum of the chroma subcomponents, in the XFIXES_POINTER_TO_YUV macro, must wrap around the unsigned char type range, for the calculation to be correct. So, we take its modulo to that range. git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@551 f606c939-3180-4ac9-a4b8-4b8779d57d0a --- recordmydesktop/src/rmd_get_frame.c | 15 +++++--- recordmydesktop/src/rmd_yuv_utils.c | 68 ++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/recordmydesktop/src/rmd_get_frame.c b/recordmydesktop/src/rmd_get_frame.c index 045368c..99ca723 100644 --- a/recordmydesktop/src/rmd_get_frame.c +++ b/recordmydesktop/src/rmd_get_frame.c @@ -106,9 +106,10 @@ yuv->y[x_tm+(i-x_offset)+(k+y_tm-y_offset)*yuv->y_width]=\ (yuv->y[x_tm+(i-x_offset)+(k-y_offset+y_tm)*yuv->y_width]*\ (UCHAR_MAX-data[(j*RMD_ULONG_SIZE_T)+__ABYTE])+\ - (Yr[data[(j*RMD_ULONG_SIZE_T)+__RBYTE]]+\ - Yg[data[(j*RMD_ULONG_SIZE_T)+__GBYTE]] +\ - Yb[data[(j*RMD_ULONG_SIZE_T)+__BBYTE]])*\ + ( ( Yr[data[(j*RMD_ULONG_SIZE_T)+__RBYTE]]+\ + Yg[data[(j*RMD_ULONG_SIZE_T)+__GBYTE]] +\ + Yb[data[(j*RMD_ULONG_SIZE_T)+__BBYTE]] ) % \ + ( UCHAR_MAX + 1 ) ) * \ data[(j*RMD_ULONG_SIZE_T)+__ABYTE])/UCHAR_MAX ;\ if((k%2)&&(i%2)){\ avg3=AVG_4_PIXELS(data,\ @@ -128,13 +129,17 @@ (yuv->u[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\ yuv->uv_width]*\ (UCHAR_MAX-avg3)+\ - (Ur[avg2] + Ug[avg1] +UbVr[avg0])*avg3)/UCHAR_MAX;\ + ( (Ur[avg2] + Ug[avg1] + UbVr[avg0]) % \ + ( UCHAR_MAX + 1 ) ) * avg3 ) / \ + UCHAR_MAX;\ yuv->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\ yuv->uv_width]=\ (yuv->v[x_2+(i-x_offset)/2+((k-y_offset)/2+y_2)*\ yuv->uv_width]*\ (UCHAR_MAX-avg3)+\ - (UbVr[avg2] + Vg[avg1] +Vb[avg0])*avg3)/UCHAR_MAX;\ + ( ( UbVr[avg2] + Vg[avg1] + Vb[avg0] ) % \ + ( UCHAR_MAX + 1 ) ) * avg3 ) / \ + UCHAR_MAX; \ }\ }\ }\ diff --git a/recordmydesktop/src/rmd_yuv_utils.c b/recordmydesktop/src/rmd_yuv_utils.c index 8996ad7..5da501b 100644 --- a/recordmydesktop/src/rmd_yuv_utils.c +++ b/recordmydesktop/src/rmd_yuv_utils.c @@ -1,9 +1,9 @@ /****************************************************************************** -* recordMyDesktop * +* recordMyDesktop - rmd_yuv_utils.c * ******************************************************************************* * * * Copyright (C) 2006,2007,2008 John Varouhakis * -* * +* Copyright (C) 2008 Luca Bonavita * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -34,24 +34,52 @@ unsigned char Yr[256], Yg[256], Yb[256], Vg[256], Vb[256]; void MakeMatrices (void) { + int i; + + /* assuming 8-bit precision */ + float Yscale = 219.0, Yoffset = 16.0; + float Cscale = 224.0, Coffset = 128.0; + float RGBscale = 255.0; + + float r, g, b; + float yr, yg, yb; + float ur, ug, ub; + float vg, vb; /* vr intentionally missing */ + + /* as for ITU-R BT-601-6 specifications: */ + r = 0.299; + b = 0.114; + g = 1.0 - r - b; + + /* as a note, here are the coefficients + as for ITU-R BT-709 specifications: + r=0.2126; b=0.0722; g=1.0-r-b; */ + + yr = r * Yscale / RGBscale; + yg = g * Yscale / RGBscale; + yb = b * Yscale / RGBscale; + ur = ( -0.5 * r / ( 1 - b ) ) * Cscale / RGBscale; + ug = ( -0.5 * g / ( 1 - b ) ) * Cscale / RGBscale; + ub = ( 0.5 * Cscale / RGBscale); + /* vr = ub so UbVr = ub*i = vr*i */ + vg = ( -0.5 * g / ( 1 - r ) ) * Cscale / RGBscale; + vb = ( -0.5 * b / ( 1 - r ) ) * Cscale / RGBscale; + + for( i = 0 ; i < 256 ; i++ ) { + + Yr[i] = (unsigned char) roundf( Yoffset + yr * i ); + Yg[i] = (unsigned char) roundf( yg * i ); + Yb[i] = (unsigned char) roundf( yb * i ); + + Ur[i] = (unsigned char) roundf( Coffset + ur * i ); + Ug[i] = (unsigned char) roundf( ug * i ); + UbVr[i] = (unsigned char) roundf( ub * i ); + + Vg[i] = (unsigned char) roundf( vg * i ); + Vb[i] = (unsigned char) roundf( Coffset + vb * i ); + + } - for (i = 0; i < 256; i++) - Yr[i] = (2104.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Yg[i] = (4130.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Yb[i] = (802.0 * i) / 8192.0; - - for (i = 0; i < 256; i++) - Ur[i] = 37.8 - (1204.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Ug[i] = 74.2 - (2384.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - UbVr[i] = (3598.0 * i) / 8192.0 ; - - for (i = 0; i < 256; i++) - Vg[i] = 93.8 - (3013.0 * i) / 8192.0 + 8.0; - for (i = 0; i < 256; i++) - Vb[i] = 18.2 - (585.0 * i) / 8192.0 + 8.0; } + -- cgit v1.2.3