Manipulating data with TVFBitmap

TVFBitmap is a wrapper class for the VFBitmap VC++ instance objects passed by Virtual Dub to external filters (for example, the src and dst fields in TFilterActivation). It encapsulates the behaviour of that instance objects providing run-time access to its virtual methods. You can also use TVFBitmap to create your own bitmaps and run Virtual Dub code on it.

Accessing VirtualDub's bitmap manipulation functions from external video filters is possible since VirtualDub 1.2. These perform a number of useful tasks such as rectangle fills, colour translation, bitmap format conversions, and stretch blits. These routines are quite fast and can save you development time.

Avisynth does not support any of the VFBitmap functions that process image data, and will likely throw an error if you call any of the functions that are marked.

Initialising vtable support

VFBitmap functions are virtual, and VirtualDub uses a bit of a hack to allow external video filters to create VFBitmaps, which requires initialising vtable pointers.  To gain access to the VFBitmap vtable pointers, you can use the function INITIALIZE_VTBLS. The vtable pointers are also automatically initialised when a wrapper to a VFBitmap VC++ instance object is created or when a clone of such an instance object is created.

You create VFBitmaps using the constructor CreateNew of the class TVFBitmap. If you atempt to create a new VFBitmap instance object without having the virtual table pointer initialised an exception occurs.

VFBitmap pixel formats

Different VFBitmap functions work on 8, 16, 24, and 32-bit bitmaps. Here is how they are defined:

depth Layout in a dword R mask G mask B mask Description
8
  C
N/A N/A N/A 8-bit paletted format
16
    R G B
0x7c00 0x03e0 0x001f 5-5-5 (16-bit) BGR
16
  R G B
0xf800 0x07e0 0x001f 5-6-5 (16-bit) BGR (seldom used)
24
  R G B
0xff0000 0x00ff00 0x0000ff 24-bit BGR format
32
  R G B
0x00ff0000 0x0000ff00 0x000000ff 32-bit BGRA format

All pixel formats are supported by Window GDI and the DirectDraw HEL, so bitmap data is interchangeable between VirtualDub and the various Windows APIs.  The brunt of most VirtualDub video filter work is done in 32-bit, but you may find the various conversion functions useful.  They are significantly faster than the 16-bit GDI in Windows 95/98.

Notice that 16-bit 565 RGB has the same depth value as 16-bit 555 RGB.  The 565 format is only supported by a few functions, and by default depth==16 implies the 555 format.

Creating and using VFBitmap instance objects

The TVFBitmap class can be used in two different ways. First, it can be used to create a wrapper around VC++ VFBitmap instance objects that are returned from Virtualdub. That basically means the two buffers fa^.src and fa^.dst. Ultimatly, the reason why you create a wrapper around these instance objects is to use the functions provided by Virtualdub. Have a look at this functions in the reference to TVFBitmap. To create a wrapper around a VFBitmap instance object coming from virtualdub you use the constructor CreateWrapper of TVFBitmap:

constructor TVFBitmap.CreateWrapper(const aCObj: PCObj_VFBitmap);

After creating the wrapper around aCObj, you can use the functions provided by VirtualDub to which the TVFBitmap class provides access. When destroying the wrapper in the end, of course only the wrapper is destroyed and the VFBitmap instance object remains untouched.

var Bitmap: TVFBitmap;
begin
  ...
  Bitmap := TVFBitmap.CreateWrapper(fa^.dst);
  Bitmap.BitBlt(0,0,fa^.src,100,100,300,300);
  Bitmap.Destroy;
  ...
end;

The second use of the TVFBitmap class is to create new VFBitmap instance objects. There are 3 constructors in the TVFBitmap class to do that:

constructor TVFBitmap.CreateClone(const aCObj: PCObj_VFBitmap);
constructor TVFBitmap.CreateNew(w: TPixDim; h: TPixDim; depth: Integer);
constructor TVFBitmap.CreateNew(bih: PBitmapInfoHeader);

The first one creates a new VFBitmap instance object that is an exact copy of the one given as aCObj. The second and third ones create new empty VFBitmap instance objects, including the allocation of memory for data. Afterwards, you can use the objects created to access VirtualDub bitmap manipulation functions, just like you would do with the wrapper.