diff -Naur libv4l-0.4.3/libv4lconvert/bayer.c libv4l-0.4.3_bayer_white_balance/libv4lconvert/bayer.c
--- libv4l-0.4.3/libv4lconvert/bayer.c	2008-08-06 10:40:53.000000000 +0200
+++ libv4l-0.4.3_bayer_white_balance/libv4lconvert/bayer.c	2008-09-14 23:50:51.000000000 +0200
@@ -611,3 +611,166 @@
   v4lconvert_border_bayer_line_to_y(bayer + width, bayer, ydst, width,
     !start_with_green, !blue_line);
 }
+
+
+void v4lconvert_bayer_white_balance(const unsigned char *bayer,
+                                    int width, int height, unsigned int pixfmt)
+{
+    unsigned long r=0,g=0,b=0,tmp;
+    unsigned long exr,exg, exb;
+    unsigned char *buff;
+    int x, y;
+    
+    tmp = width*height - 0xffff;
+    if (tmp < 0)
+        return;
+    
+    buff = bayer;
+    tmp = 0;
+    
+    /* at first, we calculate average value for each color (red, green, blue) */
+    switch (pixfmt) {
+        case V4L2_PIX_FMT_SBGGR8:
+            for (y=0; (y < height) && (tmp < 0xffff); y+=2){
+                for (x=0; (x < width) && (tmp < 0xffff); x+=2){
+                    b += buff[x];
+                    g += buff[x+1] >> 1;
+                    g += buff[x+width] >> 1;
+                    r += buff[x+width+1];
+
+                    tmp ++;
+                }
+                buff += (width <<1);
+            }
+            break;
+        case V4L2_PIX_FMT_SRGGB8:
+            for (y=0; (y < height) && (tmp < 0xffff); y+=2){
+                for (x=0; (x < width) && (tmp < 0xffff); x+=2){
+                    r += buff[x];
+                    g += buff[x+1] >> 1;
+                    g += buff[x+width] >> 1;
+                    b += buff[x+width+1];
+
+                    tmp ++;
+                }
+                buff += (width <<1);
+            }
+            break;
+        case V4L2_PIX_FMT_SGBRG8:
+            for (y=0; (y < height) && (tmp < 0xffff); y+=2){
+                for (x=0; (x < width) && (tmp < 0xffff); x+=2){
+                    g += buff[x];
+                    b += buff[x+1] >> 1;
+                    r += buff[x+width] >> 1;
+                    g += buff[x+width+1];
+
+                    tmp ++;
+                }
+                buff += (width <<1);
+            }
+            break;
+        case V4L2_PIX_FMT_SGRBG8:
+            for (y=0; (y < height) && (tmp < 0xffff); y+=2){
+                for (x=0; (x < width) && (tmp < 0xffff); x+=2){
+                    g += buff[x];
+                    r += buff[x+1] >> 1;
+                    b += buff[x+width] >> 1;
+                    g += buff[x+width+1];
+
+                    tmp ++;
+                }
+                buff += (width <<1);
+            }
+            break;
+        default:
+            return;
+    }
+    
+    r = r >> 16;
+    g = g >> 16;
+    b = b >> 16;
+    
+    if (r == 0)
+        r = 1;
+    if (g == 0)
+        g = 1;
+    if (b == 0)
+        b = 1;
+    
+    // now calculate variance from average of all colors
+    exr = ((r+g+b) << 16) / (3*r);
+    exg = ((r+g+b) << 16) / (3*g);
+    exb = ((r+g+b) << 16) / (3*b);
+    
+    //printf("pomer barev je: %d %d %d (%d %d %d) \n", exr, exg, exb, r, g, b);
+    
+    
+    // change colors...
+    buff = bayer;
+    
+    switch (pixfmt) {
+        case V4L2_PIX_FMT_SBGGR8:
+            for (y=0; (y < height); y+=2){
+                for (x=0; (x < width); x+=2){
+                    tmp = (buff[x]         * exb);
+                    buff[x]         = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+1]       * exg);
+                    buff[x+1]       = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width]   * exg);
+                    buff[x+width]   = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width+1] * exr);
+                    buff[x+width+1] = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                }
+                buff += (width << 1);
+            }
+            break;
+        case V4L2_PIX_FMT_SRGGB8:
+            for (y=0; (y < height); y+=2){
+                for (x=0; (x < width); x+=2){
+                    tmp = (buff[x]         * exr);
+                    buff[x]         = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+1]       * exg);
+                    buff[x+1]       = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width]   * exg);
+                    buff[x+width]   = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width+1] * exb); 
+                    buff[x+width+1] = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                }
+                buff += (width << 1);
+            }
+            break;
+        case V4L2_PIX_FMT_SGBRG8:
+            for (y=0; (y < height); y+=2){
+                for (x=0; (x < width); x+=2){
+                    tmp = (buff[x]         * exg);
+                    buff[x]         = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+1]       * exb);
+                    buff[x+1]       = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width]   * exr);
+                    buff[x+width]   = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width+1] * exg);
+                    buff[x+width+1] = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                }
+                buff += (width << 1);
+            }
+            break;
+        case V4L2_PIX_FMT_SGRBG8:
+            for (y=0; (y < height); y+=2){
+                for (x=0; (x < width); x+=2){
+                    tmp = (buff[x]         * exg);
+                    buff[x]         = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+1]       * exr);
+                    buff[x+1]       = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width]   * exb);
+                    buff[x+width]   = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                    tmp = (buff[x+width+1] * exg);
+                    buff[x+width+1] = (tmp > 0xffffff) ? 0xff : tmp >> 16; 
+                }
+                buff += (width << 1);
+            }
+            break;
+        default:
+            return;
+    }   
+    
+}
diff -Naur libv4l-0.4.3/libv4lconvert/libv4lconvert.c libv4l-0.4.3_bayer_white_balance/libv4lconvert/libv4lconvert.c
--- libv4l-0.4.3/libv4lconvert/libv4lconvert.c	2008-09-03 12:46:37.000000000 +0200
+++ libv4l-0.4.3_bayer_white_balance/libv4lconvert/libv4lconvert.c	2008-09-09 15:17:09.000000000 +0200
@@ -391,6 +391,9 @@
     case V4L2_PIX_FMT_SGBRG8:
     case V4L2_PIX_FMT_SGRBG8:
     case V4L2_PIX_FMT_SRGGB8:
+      
+      v4lconvert_bayer_white_balance(src, dest_fmt->fmt.pix.width, dest_fmt->fmt.pix.height, src_fmt->fmt.pix.pixelformat);
+      
       switch (dest_fmt->fmt.pix.pixelformat) {
       case V4L2_PIX_FMT_RGB24:
 	v4lconvert_bayer_to_rgb24(src, dest, dest_fmt->fmt.pix.width,
diff -Naur libv4l-0.4.3/libv4lconvert/libv4lconvert-priv.h libv4l-0.4.3_bayer_white_balance/libv4lconvert/libv4lconvert-priv.h
--- libv4l-0.4.3/libv4lconvert/libv4lconvert-priv.h	2008-09-03 11:43:16.000000000 +0200
+++ libv4l-0.4.3_bayer_white_balance/libv4lconvert/libv4lconvert-priv.h	2008-09-09 15:15:26.000000000 +0200
@@ -148,6 +148,9 @@
 void v4lconvert_bayer_to_yuv420(const unsigned char *bayer,
   unsigned char *yuv, int width, int height, unsigned int pixfmt);
 
+void v4lconvert_bayer_white_balance(const unsigned char *bayer,
+                                    int width, int height, unsigned int pixfmt);
+
 void v4lconvert_rotate90_rgbbgr24(const unsigned char *src, unsigned char *dst,
   int destwidth, int destheight);
 
