BLOAD and BSAVE understand three families of graphics files:
* FreeBASIC/QuickBASIC BSAVE memory blocks.
* Windows/OS2 bitmap files, normally using the .bmp extension.
* Portable Network Graphics files, normally using the .png extension.
The BSAVE block format is useful when a program wants to store raw screen or image memory exactly as FreeBASIC sees it. BMP and PNG are useful when the file should be opened by other graphics tools.
Format selection
File marker or name || Meaning ||
&hFD || QuickBASIC BSAVEd block. BLOAD can read this. ||
&hFE || FreeBASIC BSAVEd block. BSAVE writes this format unless the file name ends in .bmp or .png. ||
&h42, ASC("B") || Possible BMP file. BLOAD seeks back to the start and validates the full BMP header. ||
&h89 followed by the PNG signature || Possible PNG file. BLOAD seeks back to the start and validates its chunks and checksums. ||
.bmp extension || BSAVE writes a BMP file instead of a FreeBASIC BSAVE block. The extension check is case-insensitive. ||
.png extension || BSAVE writes a PNG file instead of a FreeBASIC BSAVE block. The extension check is case-insensitive. ||
FreeBASIC BSAVE block
A FreeBASIC BSAVE block starts with an &hFE marker followed by a 32-bit little-endian byte count.
Offset Size Description
0 1 &hFE, FreeBASIC BSAVE block marker
1 4 Data size in bytes, little-endian unsigned 32-bit value
5 ... Raw image or memory bytes
? ... Optional palette data when saving an indexed screen
BSAVE writes this format for any output file whose name does not end in .bmp or .png.
When saving from the current graphics screen, BSAVE writes at most the current screen pitch multiplied by the screen height. When the current graphics mode has an indexed palette, BSAVE also writes palette entries after the raw pixel data.
When saving from an explicit source pointer, BSAVE writes the requested number of bytes from that address. In that case the caller is responsible for choosing a sensible size.
QuickBASIC BSAVE block
BLOAD can also read the older QuickBASIC block marker, &hFD. That format stores a 16-bit little-endian byte count after four bytes that FreeBASIC ignores.
Offset Size Description
0 1 &hFD, QuickBASIC BSAVE block marker
1 4 Ignored by FreeBASIC
5 2 Data size in bytes, little-endian unsigned 16-bit value
7 ... Raw image or memory bytes
? ... Optional palette data
FreeBASIC BSAVE does not write the QuickBASIC &hFD form. It writes the newer &hFE form instead.
BLOAD with BSAVE blocks
BLoad filename [, dest [, pal]]
If dest is omitted, BLOAD copies the raw bytes into the current graphics screen. If the file contains more bytes than the screen can hold, the load is truncated to the screen size.
If dest is supplied, BLOAD copies the raw bytes to that address instead. For BSAVE blocks, this is a straight memory load. The destination must point at enough writable memory for the data being loaded.
Palette data is only useful for indexed graphics modes. If pal is omitted while loading to the screen, FreeBASIC loads the palette into the current graphics device palette when palette data is present.
BMP files
BLOAD treats a file beginning with &h42 as a possible BMP file, but the full BMP header must still be valid. The loader understands common uncompressed BMP headers, including the old OS/2 core header and Windows bitmap info headers.
The BMP loader handles palette BMPs and 16-bit, 24-bit, and 32-bit BMP data. One-bit and four-bit indexed BMP data are expanded while loading. Top-down BMP files, identified by a negative height, are accepted for uncompressed and bitfield BMP data.
RLE-compressed BMP files should not be relied on. Use uncompressed BMP files for portable BLOAD/BSAVE work.
BSAVE as BMP
BSave( filename, source [,[ size ][,{ pal | pal, bitsperpixel }]] )
If the file name ends in .bmp, BSAVE writes a Windows BMP file instead of a FreeBASIC BSAVE block.
* 8-bit indexed graphics can be saved as 8-bit BMP, or as 24-bit BMP when a higher output depth is requested.
* 16-bit graphics are saved as 24-bit BMP.
* 32-bit graphics are saved as 32-bit BMP by default, or as 24-bit BMP if 24 bits per pixel is requested.
* Rows are padded as required by the BMP format.
* Palette output is written for 8-bit BMP files.
PNG files
BLOAD identifies PNG input by its standard eight-byte signature. The loader validates chunk CRCs and the zlib Adler-32 checksum before accepting the image. It supports all standard PNG color types, their permitted 1-, 2-, 4-, 8-, and 16-bit sample depths, the five scanline filters, and both normal and Adam7-interlaced layouts.
Indexed and grayscale PNG files can be loaded into an 8-bit target. True-color data requires a 16-bit or 32-bit target. Alpha and tRNS transparency are retained by 32-bit targets and discarded by 16-bit or indexed targets.
If the file name passed to BSAVE ends in .png, BSAVE writes PNG instead of a raw memory block:
* 8-bit graphics are saved as an indexed PNG by default, or true-color when a higher output depth is requested.
* 16-bit graphics are converted from RGB565 to 24-bit true-color PNG.
* 32-bit graphics are saved with alpha by default, or as 24-bit true-color if 24 bits per pixel is requested.
* The encoder chooses a scanline filter for each row and writes a standard zlib/DEFLATE stream.
PNG support is implemented inside gfxlib2. Programs using BLOAD or BSAVE do not need to link libpng or zlib.
Choosing a format
Use a BSAVE block when both the writer and reader are FreeBASIC or QuickBASIC-style programs and you want a simple raw memory dump. This is fast and small, but it is tied to the screen mode, image layout, pitch, and palette assumptions of the program that reads it.
Use BMP when simple uncompressed interchange is important. Use PNG when smaller files, lossless compression, or alpha transparency are useful. Both carry dimensions and color-format information and can be inspected, edited, or generated by normal image tools.
Common mistakes
* Loading a BSAVE block into the wrong screen mode can produce scrambled output because the raw bytes no longer match the destination layout.
* Loading to a pointer does not allocate memory. Allocate the image or buffer first.
* A file starting with the letter B is not automatically a valid BMP. BLOAD checks the BMP header after seeing the first byte.
* A .bmp file saved by BSAVE is not the same format as a FreeBASIC BSAVE block. The extension selects the BMP writer.
* A .png file saved by BSAVE is not the same format as a FreeBASIC BSAVE block. The extension selects the PNG writer.
See also