Current version

v1.10.4 (stable)

Navigation

Main page
Archived news
Downloads
Documentation
   Capture
   Compiling
   Processing
   Crashes
Features
Filters
Plugin SDK
Knowledge base
Contact info
Forum
 
Other projects
   Altirra

Search

Calendar

« February 2013 »
S M T W T F S
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28    

Archives

01 Dec - 31 Dec 2013
01 Oct - 31 Oct 2013
01 Aug - 31 Aug 2013
01 May - 31 May 2013
01 Mar - 31 Mar 2013
01 Feb - 29 Feb 2013
01 Dec - 31 Dec 2012
01 Nov - 30 Nov 2012
01 Oct - 31 Oct 2012
01 Sep - 30 Sep 2012
01 Aug - 31 Aug 2012
01 June - 30 June 2012
01 May - 31 May 2012
01 Apr - 30 Apr 2012
01 Dec - 31 Dec 2011
01 Nov - 30 Nov 2011
01 Oct - 31 Oct 2011
01 Sep - 30 Sep 2011
01 Aug - 31 Aug 2011
01 Jul - 31 Jul 2011
01 June - 30 June 2011
01 May - 31 May 2011
01 Apr - 30 Apr 2011
01 Mar - 31 Mar 2011
01 Feb - 29 Feb 2011
01 Jan - 31 Jan 2011
01 Dec - 31 Dec 2010
01 Nov - 30 Nov 2010
01 Oct - 31 Oct 2010
01 Sep - 30 Sep 2010
01 Aug - 31 Aug 2010
01 Jul - 31 Jul 2010
01 June - 30 June 2010
01 May - 31 May 2010
01 Apr - 30 Apr 2010
01 Mar - 31 Mar 2010
01 Feb - 29 Feb 2010
01 Jan - 31 Jan 2010
01 Dec - 31 Dec 2009
01 Nov - 30 Nov 2009
01 Oct - 31 Oct 2009
01 Sep - 30 Sep 2009
01 Aug - 31 Aug 2009
01 Jul - 31 Jul 2009
01 June - 30 June 2009
01 May - 31 May 2009
01 Apr - 30 Apr 2009
01 Mar - 31 Mar 2009
01 Feb - 29 Feb 2009
01 Jan - 31 Jan 2009
01 Dec - 31 Dec 2008
01 Nov - 30 Nov 2008
01 Oct - 31 Oct 2008
01 Sep - 30 Sep 2008
01 Aug - 31 Aug 2008
01 Jul - 31 Jul 2008
01 June - 30 June 2008
01 May - 31 May 2008
01 Apr - 30 Apr 2008
01 Mar - 31 Mar 2008
01 Feb - 29 Feb 2008
01 Jan - 31 Jan 2008
01 Dec - 31 Dec 2007
01 Nov - 30 Nov 2007
01 Oct - 31 Oct 2007
01 Sep - 30 Sep 2007
01 Aug - 31 Aug 2007
01 Jul - 31 Jul 2007
01 June - 30 June 2007
01 May - 31 May 2007
01 Apr - 30 Apr 2007
01 Mar - 31 Mar 2007
01 Feb - 29 Feb 2007
01 Jan - 31 Jan 2007
01 Dec - 31 Dec 2006
01 Nov - 30 Nov 2006
01 Oct - 31 Oct 2006
01 Sep - 30 Sep 2006
01 Aug - 31 Aug 2006
01 Jul - 31 Jul 2006
01 June - 30 June 2006
01 May - 31 May 2006
01 Apr - 30 Apr 2006
01 Mar - 31 Mar 2006
01 Feb - 29 Feb 2006
01 Jan - 31 Jan 2006
01 Dec - 31 Dec 2005
01 Nov - 30 Nov 2005
01 Oct - 31 Oct 2005
01 Sep - 30 Sep 2005
01 Aug - 31 Aug 2005
01 Jul - 31 Jul 2005
01 June - 30 June 2005
01 May - 31 May 2005
01 Apr - 30 Apr 2005
01 Mar - 31 Mar 2005
01 Feb - 29 Feb 2005
01 Jan - 31 Jan 2005
01 Dec - 31 Dec 2004
01 Nov - 30 Nov 2004
01 Oct - 31 Oct 2004
01 Sep - 30 Sep 2004
01 Aug - 31 Aug 2004

Stuff

Powered by Pivot  
XML: RSS feed 
XML: Atom feed 

§ The BI_BITFIELDS bitmap type

Everyone knows how to deal with bitmaps in Windows, right? The ones that are described by BITMAPINFOHEADER?

Enter a seldom-used bitmap mode called BI_BITFIELDS.

Most bitmaps in Windows have their biCompression field set to BI_RGB, which just indicates a straight indexed or direct-mapped RGB encoding. This encompasses indexed color formats of 2, 4, 16, or 256 colors, as well as 16-bit, 24-bit, and 32-bit direct color encodings. That handles virtually everything that you'll ever encounter, except for one gotcha. People who are new to BITMAPINFOHEADER often screw up in handling the 16-bit format, because they don't realize that it is actually 15 bits -- five bits of red/green/blue each, and one unused high bit. This is known as a 555 or 1555 encoding. Despite this format having only 15 significant bits, it still uses a bit depth value of 16, which is what confuses newbies.

Windows does actually support a true 16-bit encoding, which consists of five bits of red and blue each and six bits of green, or a 565 encoding. You can't get to it via BI_RGB, however; you have to use the special BI_BITFIELDS compression value instead. This adds three bit masks after the biClrImportant field that specify the exact bit locations of the red, green, and blue fields. When these bit masks are 0000F800, 000007E0, and 0000001F, respectively, the bitmap uses a 565 16-bit encoding. Windows GDI supports this format because a lot of popular graphics hardware used to support only a particular 16-bit frame buffer format and 565 was one of the common ones.

The reason I bring this up is that I recently started rewriting the part of VirtualDub that handles BI_BITFIELDS images as part of some other work. You might be wondering if anyone uses BI_BITFIELDS encoding, especially in AVI files, and the answer is that it's extremely rare. However, one thing I've learned from working on this program is that almost anything is possible will eventually show up in the wild; for instance, I once had to fix a crash caused by trying to import images produced by a popular SNES emulator that used BITMAPCOREHEADER instead of BITMAPINFOHEADER in the format block. Anyway, a particularly interesting way you can get BI_BITFIELDS in a video stream is using GraphEdit to decompress a video from a decompression filter that supports 565 for display performance issues and happens to have it listed first in the format list of the output pin. Therefore, it's one of the things I've been regression testing.

...Only to discover that most other programs don't handle BI_BITFIELDS properly to begin with.

It turns out that there are only four direct color formats that Windows GDI is guaranteed to handle: 16-bit (555), 16-bit (565), 24-bit (888), and 32-bit (888). Win9x OSes will only handle BI_BITFIELDS images with these four encodings. Of these, three of them are accessible via BI_RGB, with 565 being the only one that absolutely requires the bitfield encoding. Presumably for this reason, it seems that just about every video technology I have installed was written with the assumption that BI_BITFIELDS always means 565, including core components of Microsoft DirectShow like the Color Space Converter. If you use BI_BITFIELDS with the 555 masks (00007C00 / 000003E0 / 0000001F), the video player still tries to decode it as 565 and displays garbage. Hey guys, know those other fields in the bitmap structure? You're supposed to check them!

When things get really fun, however, is when you take into account that Windows NT GDI is considerably more powerful and will accept arbitrary non-overlapping, contiguous bit masks. Current versions of VirtualDub fall back to GDI's BitBlt() when encountering a BI_BITFIELDS video stream, and thus if you are running on Windows NT4/2000/XP/Vista, you'll be able to open most BI_BITFIELDS encoded videos. I wrote a test program to convert a BMP image sequence to BI_BITFIELDS encoded AVI files with user-specified bit masks, and GDI handled many other popular formats through BI_BITFIELDS, such as BGR 555 and RGB 444, and even 2/10/10/10. I say almost, because GDI doesn't seem to like it if you use a zero bit mask for a channel, although interestingly it doesn't mind if you use 0x10000 in a 16-bit format. Ultimately useless, but I list it here for completeness and since it was trivial to get it working in the rewritten bitfields code.

I didn't have much of a point in writing this other than sharing what I'd found during testing, but if you were looking for a conclusion here, I'd say: make sure you validate the bit masks when processing BI_BITFIELDS, and if you write bitmaps or video with that format, only do so for 565 and otherwise use BI_RGB whenever possible.

(Read more....)