Fuzix‎ > ‎

A Proglet: windows bmp viewer

posted Jul 3, 2016, 6:44 AM by Brett Gordon   [ updated Jul 3, 2016, 4:00 PM ]
I hacked a small program to use Fuzix's direct video transfer ioctls.  Having some previous experience with the window .bmp format, I decided to try for a simple bmp viewer.  Window bmp files are actually pretty flexible, allowing for 1,2,4,8,16,32 bits pixel encodings.  Current Fuzix's (Dragon, CoCo3 ports, as of this writing ) support only a basic 1 bpp (bit-per-pixel) screen, so the first logical step is to get the viewer to display a taylor-made 1 bpp bitmap I created via Gimp:

Not bad... but what if we want to view a bmp in a higher bbp?  So I added a simple transposer for a 8 bit color depth.  Basic process is a follows:  get a 8 bit pixel datum, use it as a index to 24 bit color value from the .bmp's color table.  Convert the 24 bit RGB to an intensity:  

 uint8_t intensity( struct bmp_palette *p ){
uint16_t c;
c = (p->red * 2);
c += (p->green * 5);
c += p->blue;
return c/8;

This formula is a "I have no fast divide" approximation of this formula (from wikipedia): Y = .3R + .6G + .1B.  If the resultant intensity is greater than 127 then plot the pixel as a 1, else plot it as a 0.  This is the results:

Yup... the down sampling worked - Let's add some super-simple dithering by taking the quantization error for each pixel and adding it to the next pixel processed in the line:

Yay!  Ken almost has a face again!  Not bad - this method is still fairly fast, but produces simple dithering's characteristic pin-striping. For the cost of some addition math and a couple error buffers we can add some Floyd-Steinberg Dithering:

Now this is coming close to The Gimp's dithering as seen in the first screenshot.  It looks like gimp is narrowing the contrast somewhat.  It takes 45 seconds to render this bitmap on a CoCo3 running at 1.79 Mhz !  

Oh... why is it in Blue ?  We don't have the paletting kernel interface designed yet! :)

And for comparison: here is the source file, a 8bpp image:


Support for 2 and 4 bpp shouldn't be too hard or different than above.  Support for 24 bit images is probably silly, as these formats take nearly an entire floppy disk to store, and would be sort of impractical to bother with.

-- several hours later --

Whoops:  Inexact file format specs lead me to miss interpret the color/palette format.  Now here's our 8 bpp image again using the correct colors. Notice the ceiling highlights are starting to pop out.  Contrast is still pretty heavy:

OK... I have refactored the code, and these are the supported formats:

-- paletted modes --
1 bpp  (fast)
2 bpp  (hardly ever found in wild)
4 bpp  
8 bpp
-- RGB modes --
16 bpp
24 bpp
32 bpp**
no compression is supported.

I also added a "-d" command line option for turning *off* the dithering.

** seems to work, but the 192k large file I'm using to test this format is broken.  I'm assuming our host to target file system maker (ucp) is writing bad large files, because previous tests with large, native (>1M) tar files did work.  A "od -hx" reveals the file content's past the 137th line are all zeros.