Home |
Save As |
Save AsThe Output Format option specifies whether Image Convert should generate C++ source code or binary data. When C++ source data structures are generated, Image Convert writes a normal ASCII file that can be opened and modified with any editor. This ASCII file contains the bitmap data array, along with the corresponding PegBitmap structure definition. If an optimal palette is generated, the C++ file will also contain the custom palette. When binary format is selected, Image Convert generates a binary data file containing one or more PegBitmap data structures and bitmap data definitions. The binary file starts with an 8 byte header as shown below: // Header, one occurrence per binary image file: char cVersion[4] // four byte version string, "1.00" UCHAR uReservedA // 1 byte reserved UCHAR uHavePalette // 1 byte palette flag UCHAR uReservedB[2] // 2 unused bytes The uHavePalette byte of the header signals the presence or absence of a color palette in the binary file. If the binary file contains a custom palette, uHavePalette will be non-zero and the custom palette immediately follows the file header, and can be declared as shown below: UCHAR Palette[256*3] // only present when custom palette is generated. Following the header and optional palette data are the bitmap header and bitmap data fields. The bitmap header and data fields are repeated for each image contained in the file. Each bitmap is contained in the binary file as shown below: // repeated for each bitmap in file: Char cName[28] // bitmap name left justified UCHAR uFlags // 1 byte, PegBitmap.uFlags UCHAR uBitsPix // 1 byte, PegBitmap.uBitsPix WORD wWidth // 2 bytes, PegBitmap.wWidth (Big Endian) WORD wHeight // 2 bytes, PegBitmap.wHeight (Big Endian) WORD wReserved // 2 bytes, unused DWORD Size // 4 bytes, size of data array in bytes (Big Endian) DWORD Reserved // 4 bytes, unused UCHAR uData[Size] // bitmap data values For each bitmap, Size bytes of bitmap data follow the bitmap header information. When multiple PegBitmaps are generated using batch conversion, each successive bitmap header immediately follows the previous bitmap data. There are no padding or alignment bytes inserted between bitmaps. For multi-byte fields such as wWidth and wHeight, byte swapping is required when reading the bitmap header. Image Convert always writes multibyte values MSB (most significant byte) first. Byte swapping is not required for the actual bitmap data, as this section always contains only single-byte values. Reading a bitmap or series of bitmaps from a binary file can be accomplished with the pseudo-code shown below: DWORD DWORDSwap(DWORD D) { DWORD Result; BYTE * d = (BYTE*) &D; BYTE * r = (BYTE*) &Result; r[0] = d[3]; r[1] = d[2]; r[2] = d[1]; r[3] = d[0]; return Result; } WORD WORDSwap(WORD W) { WORD Result; BYTE * w = (BYTE*) &W; BYTE * r = (BYTE*) &Result; r[0] = w[1]; r[1] = w[0]; return Result; } UCHAR * ReadBitmap(FILE * f, PegBitmap &Bitmap) { UCHAR uTemp[30]; UCHAR * pPalette; DWORD DataSize; // read in the header fread(uTemp, 1, 8, f); // does file contain a palette? if (uTemp[5]) { pPalette = new UCHAR[256 * 3]; fread(pPalette, 1, 256*3, f); } else pPalette = NULL; // read image name fread(uTemp, 1, 28, f); // read PegBitmap structure fread(&Bitmap.uFlags, 1, 1, f); fread(&Bitmap.uBitsPix, 1, 1, f); fread(&Bitmap.wWidth, 1, 2, f); fread(&Bitmap.wHeight, 1, 2, f); fread(uTemp, 1, 2, f); // skip reserved field // read data size fread(&DataSize, 1, 4, f); fread(uTemp, 1, 4, f); // skip reserved field // byte swap big endian values Bitmap.wWidth = WORDSwap(Bitmap.wWidth); Bitmap.wHeight = WORDSwap(Bitmap.wHeight); Bitmap.dTransColor = 0; DataSize = DWORDSwap(DataSize); // get bitmap image data Bitmap.pStart = new UCHAR[DataSize]; fread(Bitmap.pStart, 1, DataSize, f); return pPalette; } Note that if the binary file contains multiple bitmaps, the application software could also pass to ReadBitmap() the name of the image file to load. In that case, ReadBitmap would loop through the binary images until the correct bitmap name is found.
|