Talk:DDiCI Graphics format
xGAPICS Format
File Header (first 48 Bytes):
Off Bytes Description 0 2 Blank 2 4 Font start 6 4 Tile start 10 4 Image start 14 4 Sprite start 18 4 Image Entries start 22 4 Sprite Entries start 26 4 Blue Plane start 30 4 Green Plane start 34 4 Red Plane start 38 2 Intensity Plane start 40 2 Font Count 42 2 Tile Count 44 2 Image Count 46 2 Sprite Count
Notes:
All the "start" values need to be multiplied by 16 to get the "real" location.
The header structure is the same for EGA and CGA, but you can ignore all the "Plane start" values read from the CGA file, since CGA doesn't use planes.
Image Entries (16 Bytes each):
Off Bytes Description 0 2 Width 2 2 Height 4 4 Offset 8 8 Name (0-padded string)
Notes:
The Width value is NOT in Pixels, but rather in Bytes-per-line. So Width * Height gives you the number of bytes that need to be read. In CGA, this is the total amount of bytes for this image. In EGA, this is the number of bytes to be read FROM EACH EGA PLANE, so the actual size of the image (in bytes) is four times that size. The real width of the image (in Pixels) is Width * 8 for EGA or Width * 4 for CGA graphics.
The Offset value doesn't need to be multilpied by 16!
How to convert the RAW data to RGB values for each pixel
First, you need to know some values:
- Width (Bytes-per-line) and Height (Pixels) of the Image
- Image Offset
- "start" location (Font start, Tile start, Image start or Sprite start)
- for EGA only: Plane distance
Note on Plane distance:
All four EGA planes should have the same size. The distance can be calculated (GreenPlaneStart - BluePlaneStart), for example. The following pseudocode expects the color planes to be ordered from first to last: B-G-R-I.
Converting EGA data
First, you need to create a buffer of (Width * Height * 8) Byte values (one Byte per pixel). Start by reading the values from the Blue Plane, so scan to position (StartLocation+ImageOffset). The StartLocation is always in the Blue Plane. FOR i = 0 TO (Width*Height)-1 read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically) write ((b / 128) mod 2) to buffer at position (i*8) write ((b / 64) mod 2) to buffer at position (i*8 + 1) write ((b / 32) mod 2) to buffer at position (i*8 + 2) write ((b / 16) mod 2) to buffer at position (i*8 + 3) write ((b / 8) mod 2) to buffer at position (i*8 + 4) write ((b / 4) mod 2) to buffer at position (i*8 + 5) write ((b / 2) mod 2) to buffer at position (i*8 + 6) write ((b / 1) mod 2) to buffer at position (i*8 + 7) NEXT Now scan to position (StartLocation + PlaneDistance + ImageOffset) to read the Green Plane. FOR i = 0 TO (Width*Height)-1 read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically) add (((b / 128) mod 2) * 2) to buffer at position (i*8) add (((b / 64) mod 2) * 2) to buffer at position (i*8 + 1) add (((b / 32) mod 2) * 2) to buffer at position (i*8 + 2) add (((b / 16) mod 2) * 2) to buffer at position (i*8 + 3) add (((b / 8) mod 2) * 2) to buffer at position (i*8 + 4) add (((b / 4) mod 2) * 2) to buffer at position (i*8 + 5) add (((b / 2) mod 2) * 2) to buffer at position (i*8 + 6) add (((b / 1) mod 2) * 2) to buffer at position (i*8 + 7) NEXT Now scan to position (StartLocation + 2*PlaneDistance + ImageOffset) to read the Red Plane. FOR i = 0 TO (Width*Height)-1 read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically) add (((b / 128) mod 2) * 4) to buffer at position (i*8) add (((b / 64) mod 2) * 4) to buffer at position (i*8 + 1) add (((b / 32) mod 2) * 4) to buffer at position (i*8 + 2) add (((b / 16) mod 2) * 4) to buffer at position (i*8 + 3) add (((b / 8) mod 2) * 4) to buffer at position (i*8 + 4) add (((b / 4) mod 2) * 4) to buffer at position (i*8 + 5) add (((b / 2) mod 2) * 4) to buffer at position (i*8 + 6) add (((b / 1) mod 2) * 4) to buffer at position (i*8 + 7) NEXT Now scan to position (StartLocation + 3*PlaneDistance + ImageOffset) to read the Intensity Plane. FOR i = 0 TO (Width*Height)-1 read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically) add (((b / 128) mod 2) * 8) to buffer at position (i*8) add (((b / 64) mod 2) * 8) to buffer at position (i*8 + 1) add (((b / 32) mod 2) * 8) to buffer at position (i*8 + 2) add (((b / 16) mod 2) * 8) to buffer at position (i*8 + 3) add (((b / 8) mod 2) * 8) to buffer at position (i*8 + 4) add (((b / 4) mod 2) * 8) to buffer at position (i*8 + 5) add (((b / 2) mod 2) * 8) to buffer at position (i*8 + 6) add (((b / 1) mod 2) * 8) to buffer at position (i*8 + 7) NEXT
After this is done, you have the color index for every pixel in your buffer. To get the corresponding RGB value, just use the following color table:
Index Name RGB value (HEX) 0 Black 000000 1 Dark Blue 0000AA 2 Dark Green 00AA00 3 Dark Cyan 00AAAA 4 Dark Red AA0000 5 Purple AA00AA 6 Brown AAAA00 7 Grey AAAAAA 8 Dark Grey 555555 9 Blue 5555FF A Green 55FF55 B Cyan 55FFFF C Red FF5555 D Pink FF55FF E Yellow FFFF55 F White FFFFFF
For the sake of completeness here's the pseudocode to create a "Pixmap" from the buffer. We use the WritePixel(x, y, rgb) to add the color information to the "Pixmap".
CreatePixmap (w = Width*8, h = Height) FOR i = 0 to (Width*Height)-1 WritePixel(x = i mod w, y = i / w, rgb = ColorTable[Buffer[i]]) NEXT
Converting CGA data
For the CGA data, you don't need a buffer for the color indices. We'll write the pixels as we read the RAW data, using the following color table:
Index Name RGB value (HEX) 0 Black 000000 1 Cyan 55FFFF 2 Pink FF55FF 3 White FFFFFF
CreatePixmap(w = Width*4, h = Height) Scan to position (StartLocation + ImageOffset) FOR i = 0 to (Width*Height)-1 read a Byte value (b) from the file //(and proceed to the next Byte if your programming language doesn't do that automatically) WritePixel(x = (i mod w) , y = (i / w), rgb = ColorTable[(b / 64) mod 4]) WritePixel(x = (i mod w)+1, y = (i / w), rgb = ColorTable[(b / 16) mod 4]) WritePixel(x = (i mod w)+2, y = (i / w), rgb = ColorTable[(b / 4) mod 4]) WritePixel(x = (i mod w)+3, y = (i / w), rgb = ColorTable[(b / 1) mod 4]) NEXT
--K1n9 Duk3 14:46, 15 January 2011 (GMT)