| Herd Software Development
|=
DaVinci Graphics Library
|==
DaVinci Documentation Home Search Order


32 bit DIB processing made easy

If your application program only requires DIB display and no direct processing or modification, you can apply Windows API and Leonardo functions directly to the DIB data. They'll handle any distinctions that need to be made between 1, 4, 8, 16, 24 or 32 bit color depth.

But whenever you perform any direct modification of the DIB, either in memory alone for display purposes or for purposes of saving the resulting image to disk, you become responsible for insuring that bit depth is handled correctly. You've got a choice, though. You can either develop your own routines to deal with each possible bit depth the app may encounter, or you can use Leonardo's built-in RWxxxx functions and let Leonardo handle bit depth determination.

In order to simplify the development of fast processing routines, DaVinci Professional can automatically convert DIBs of any color depth to a 32 bit DIB using the ConvertDIB function. This routine is optimized for high speed, and can either be applied on its own, or indirectly on import of the image. If you set the IPF_IMPORT_DIB32 flag when calling ipImportInd, DaVinci performs the conversion for you as part of the load process.

Advantages of 32 bit DIB conversion

Disadvantages of 32 bit DIB conversion

The 32 bit DIB format

The 32 bit DIB format consists of the following elements depending on where the DIB is used.

DIBs in memory DIBs in a BMP file

(n/a) BITMAPFILEHEADER

BITMAPINFOHEADER BITMAPINFOHEADER

Bitmap data Bitmap data

Bitmap data is stored four bytes per pixel, one each to specify blue, green and red intensities, and the fourth byte is unused. This definition corresponds to the definition of an RGBQUAD structure.

DIBs with 8 or 24 bit color depth often require filler bytes at the end of each line to insure that the line length is evenly divisible by 4. As stated previously, this is unnecessary with 32 bit DIBs. This allows a single loop to process all pixels without requiring special handling for end-of-line filler bytes.

Reducing color depth once processing is complete

Reduciing a 32 bit DIB to a lower bit depth is done using either with the functions ConvertDIB, DitherTo1ID, DitherTo4, DitherTo8, ConvertDIB orTransformDIB.

The ConvertDIB function uses simple color mapping and is more suited to rough drafts, screen shots and other simple images where dithering would not enhance the image, while the Ditherxxx routines are designe to provide professional dithering results for images requiring more detail.

Saving DIBs at 32 bit image files

32 bit DIBs can be saved to disk as .BMP files, but this format is officially only supported for true 32 bit Windows operating systems. Windows 3.1 applications will often be unable to deal with these DIBs, and even some native 32 bit applications which rely upon internal bit depth handling might not recognize the format. It may therefore be more convenient to end users to prompt the user whether to save such images as TrueColor images, which are almost universally recognized by graphics applications.

This prompting won't be needed if the user specifies export as PNG, TIF or JPG. DaVinci automatically converts the image to 24 bits when any of these formats are specified as the output format for a 32 bit DIB.

Using HUGE pointers in 16 bit applications:

In order to process DIBs of more than 64KB in size, 16 bit applications must use huge pointers.
DWORD huge *	hpdWord;

Incrementing huge pointers can be a relatively slow process if you're not watchful. For example, when working with 24 bit DIBs, you'll need to increment each byte individually. For 32-Bit DIBs, though you can access the next pixel by simply incrementing a pointer by 32 bits, as in the following example:

Example: Determining the average color of a 32 bit DIB
int AverageBrightness(HDIB hDIB)
{
	LPBITMAPINFOHEADER	lpbmi = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
	DWORD HUGE *	hpPixel = (DWORD HUGE *) (lpbmi+1);
	DWORD	dwPixelCount = lpbmi->biWidth * lpbmi->biHeight,
		dwPixelsLeft,
		dwPixelValue,
		dwSum;

	for (dwSum=0, dwPixelsLeft=dwPixelCount; dwPixelsLeft-->0;)
	{
		dwPixelValue = *hpPixel++;
		dwSum += 	GetRValue(dwPixelValue)
			+ GetGValue(dwPixelValue)
			+ GetBValue(dwPixelValue);
	}

	return dwSum / dwPixelCount / 3;
}