diff --git a/zbar/video/vfw.c b/zbar/video/vfw.c
--- a/zbar/video/vfw.c
+++ b/zbar/video/vfw.c
@@ -81,6 +81,38 @@
 
 #define VFW_NUM_FORMATS (sizeof(vfw_formats) / sizeof(uint32_t))
 
+/** intercept capGetVideoFormat to make values returned by windows
+ *  compatible with zbar standards
+ *  @see capSetVideoFormatZbar() */
+static inline DWORD capGetVideoFormatZbar(HWND hwnd,
+                                          BITMAPINFOHEADER *bih,
+                                          WPARAM wSize)
+/* actually should be BITMAPINFO, but we believe that the caller
+   reserved place for the whole structure. BITMAPINFOHEADER lies
+   at the beginning of BITMAPINFO */
+{
+    BOOL rv = capGetVideoFormat(hwnd, bih, wSize);
+    if(rv) {
+        if (bih->biBitCount==24 && bih->biCompression==BI_RGB)
+            bih->biCompression = fourcc('B','G','R','3');
+    }
+    return(rv);
+}
+
+/** intercept capSetVideoFormat to make values passed to windows
+ *  compatible with zbar standards
+ *  @see capGetVideoFormatZbar() */
+static inline DWORD capSetVideoFormatZbar(HWND hwnd,
+                                          BITMAPINFOHEADER *bih,
+                                          WPARAM wSize)
+{
+    if (bih->biBitCount==24 &&
+            (bih->biCompression==fourcc('B','G','R','3') ||
+             bih->biCompression==fourcc('R','G','B','3')))
+        bih->biCompression = BI_RGB;
+    return capSetVideoFormat(hwnd, bih, wSize);
+}
+
 static ZTHREAD vfw_capture_thread (void *arg)
 {
     zbar_video_t *vdo = arg;
@@ -247,11 +279,11 @@
     zprintf(8, "seting format: %.4s(%08x) " BIH_FMT "\n",
             (char*)&fmt, fmt, BIH_FIELDS(bih));
 
-    if(!capSetVideoFormat(vdo->state->hwnd, bih, vdo->state->bi_size))
+    if(!capSetVideoFormatZbar(vdo->state->hwnd, bih, vdo->state->bi_size))
         return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                            "setting video format"));
 
-    if(!capGetVideoFormat(vdo->state->hwnd, bih, vdo->state->bi_size))
+    if(!capGetVideoFormatZbar(vdo->state->hwnd, bih, vdo->state->bi_size))
         return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                            "getting video format"));
 
@@ -367,12 +399,12 @@
     }
     bih->biCompression = fmt;
 
-    if(!capSetVideoFormat(vdo->state->hwnd, bih, vdo->state->bi_size)) {
+    if(!capSetVideoFormatZbar(vdo->state->hwnd, bih, vdo->state->bi_size)) {
         zprintf(4, "\tno (set fails)\n");
         return(0);
     }
 
-    if(!capGetVideoFormat(vdo->state->hwnd, bih, vdo->state->bi_size))
+    if(!capGetVideoFormatZbar(vdo->state->hwnd, bih, vdo->state->bi_size))
         return(0/*FIXME error...*/);
 
     zprintf(6, "\tactual: " BIH_FMT "\n", BIH_FIELDS(bih));
@@ -396,7 +428,7 @@
 
     if(!capSetUserData(state->hwnd, (LONG)vdo) ||
        !state->bi_size || !bih ||
-       !capGetVideoFormat(state->hwnd, bih, state->bi_size))
+       !capGetVideoFormatZbar(state->hwnd, bih, state->bi_size))
         return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_INVALID, __func__,
                            "setting up video capture"));
 
