[Oberon] FPGA - Screen.Mod

Jörg joerg.straube at iaeth.ch
Wed Oct 24 13:42:22 CEST 2018


As I said I would only take the BITMAPCOREHEADER (12 byte) instead of the BITMAPINFOHEADER (40 byte); I'm lazy and don't want to populate a lot of fields 😊
But this is only minor.

One problem is, your color table is wrong: The order of the color channels in the BMP files has to be: first byte B, second byte G, third byte R, fourth byte 0.
As you decided to use "WriteInt" (instead of Write / WriteByte), you have to take care of the endianness of WriteInt, or in other words: you have to know in what sequence WriteInt writes the four bytes of an INTEGER to the file. The sequence in WriteInt is: LSB first, MSB last. 

So for a color table in a BMP file use
red     is WriteInt(00FF0000H);
green is WriteInt(0000FF00H);
blue   is WriteInt(000000FFH);
or generally


-----Original Message-----
From: Oberon <oberon-bounces at lists.inf.ethz.ch> On Behalf Of Tomas Kral
Sent: Wednesday, October 24, 2018 11:47 AM
To: oberon at lists.inf.ethz.ch
Subject: Re: [Oberon] FPGA - Screen.Mod

> You already reached a lot.
Thank you for your encouragement. This is an improved version, that seems having correct header. Colours are still shifted both in palette
and indices.    

I store BGR as is in little endian, so as BMP expects. I fear instead of byte reversal, I may need nibble reversal which would be terribly slow, unless some magic mask and lookup used.

        (*Windows Bitmap File Header*)
        Files.Write(R, "B"); Files.Write(R, "M");
        Files.WriteInt(R, 14+40+8+128*(*7*)68*4); (*file size 768 real, 68 for faster testing*)
        Files.WriteInt(R, 0); (*reserved*)
        Files.WriteInt(R, 14+40+(*2*)16*4); (*offset of bits, 2*4 - mono, 16*4 - 4bit*)
        (*Windows Bitmap WinHeader*)
        Files.WriteInt(R, 40); (*header size*)
        Files.WriteInt(R, 1024); Files.WriteInt(R, 768); (*w,h*)
        Files.WriteInt(R, 00040001H); (*planes, bpp, should really be 0001 0004, but 0001 0004 makes oversized palette*)
        Files.WriteInt(R, 0); (*no compression*)
        Files.WriteInt(R, 0); (*size of bitmap - can be 0 if uncompressed*)
        Files.WriteInt(R, 15000); Files.WriteInt(R, 15000); (*h&vres in ppm*)
        Files.WriteInt(R, 16); Files.WriteInt(R, 16); (*colours used, important, 2/2 - mono, 16/16 - 4bit*)

        (*fixed colour table `00BBGGRRH' 00padded rgb little endian*)
        Files.WriteInt(R, 0000000H); Files.WriteInt(R, 0000080H) (*red*);
        Files.WriteInt(R, 0008000H); Files.WriteInt(R, 0008080H);
        Files.WriteInt(R, 0800000H);(*blue*) Files.WriteInt(R, 0800080H);
        Files.WriteInt(R, 0808000H);(*green*) Files.WriteInt(R, 0808080H);
        Files.WriteInt(R, 0C0C0C0H); Files.WriteInt(R, 00000FFH);
        Files.WriteInt(R, 000FF00H); Files.WriteInt(R, 000FFFFH);
        Files.WriteInt(R, 0FF0000H); Files.WriteInt(R, 0FF00FFH);
        Files.WriteInt(R, 0FFFF00H); Files.WriteInt(R, 0FFFFFFH);
        (*actual colour table*)
        (*FOR a := ms TO me BY 4 DO SYSTEM.GET(a, m); Files.WriteInt(R, m) END;*)

Tomas Kral <thomas.kral at email.cz>

More information about the Oberon mailing list