Strings in ATARI.TXT


                           ST Picture Formats
------------------
Edited by:
David Baggett
Internet:
[email protected]
(Please report errors or additions.)
Copyright (C) 1988 -- 1995 by David M. Baggett
Non-profit redistribution of this document is permitted, provided
the document is not modified in any way.
Reproduction of this document in whole or in part for commercial
purposes is expressly forbidden without the prior written consent
of David M. Baggett.
The information presented here is not guaranteed to be correct.
The editor and contributors will in no event be liable for direct,
indirect, incidental, or consequential damages resulting from the
use of the information in this document.
This document is the product of many hours of volunteer work by a
large number of people. Please respect this -- do not violate the
distribution policy.
CONTRIBUTORS
Steve Belczyk Phil Blanchfield Marcel Boom Jason Blochowiak
John Brochu** David Brooks Daniel Deimert Martyn Dryden
Neil Forsyth Stefan Hoehn Gerfried Klein G. "Maddog" Knauss
Ken MacLeod Shamus McBride Jim McCabe Lars Michael
Darek Mihocka David Mumper George Nassas Jim Omura
Chris Ridd George Seto Joe Smith Greg Wageman
Roland Waldi* Gerry Wheeler
Contents
--------
NEOchrome *.NEO
NEOchrome Animation *.ANI
DEGAS *.PI? ? = 1, 2, 3
DEGAS Elite *.PI? ? = 1, 2, 3
DEGAS Elite (Compressed) *.PC? ? = 1, 2, 3
Tiny *.TN? ? = 1, 2, 3, Y
Spectrum 512 *.SPU
Spectrum 512 (Compressed) *.SPC
Spectrum 512 (Smooshed) *.SPS
Art Director *.ART
C.O.L.R. Object Editor Mural *.MUR
Doodle *.DOO
Cyber Paint Sequence *.SEQ
Animatic Film *.FLM
Animaster Sprite Bank *.ASB
STOS *.MBK
GEM Bit Image *.IMG
GEM Bit Image, Extended *.IMG
GEM Metafile (vector graphics) *.GEM
STAD *.PAC
Imagic Film/Picture *.IC? ? = 1, 2, 3
IFF *.IFF
RGB Intermediate Format *.RGB
ComputerEyes Raw Data Format *.CE? ? = 1, 2
MacPaint *.MAC
PackBits Compression Algorithm
Introductory Information
------------------------
word = 2 bytes
long = 4 bytes
palette = Hardware color palette, stored as 16 words. First word is
color register zero (background), last word is color register
15. Each word has the form:
Bit: (MSB) 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (LSB)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
0 0 0 0 0 R2 R1 R0 0 G2 G1 G0 0 B2 B1 B0
R2 = MSB of red intensity
R0 = LSB of red intensity
G2 = MSB of green intensity
G0 = LSB of green intensity
B2 = MSB of blue intensity
B0 = LSB of blue intensity
Intensity ranges from 0 (color not present) to 7 (highest
intensity).
Example: { red = 7, green = 3, blue = 5 } -> 0735 (hex)
Caveat: It is wise to mask off the upper four bits of each
palette entry, since a few programs store special
information there (e.g., Art Studio).
The Formats
-----------
<NEOchrome> *.NEO
1 word flag byte [always 0]
1 word resolution [0 = low res, 1 = medium res, 2 = high res]
16 words palette
12 bytes filename [usually " . "]
1 word color animation limits. High bit (bit 15) set if color
animation data is valid. Low byte contains color animation
limits (4 most significant bits are left/lower limit,
4 least significant bits are right/upper limit).
1 word color animation speed and direction. High bit (bit 15) set
if animation is on. Low order byte is # vblanks per step.
If negative, scroll is left (decreasing). Number of vblanks
between cycles is |x| - 1
1 word # of color steps (as defined in previous word) to display
picture before going to the next. (For use in slide shows)
1 word image X offset [unused, always 0]
1 word image Y offset [unused, always 0]
1 word image width [unused, always 320]
1 word image height [unused, always 200]
33 words reserved for future expansion
16000 words picture data (screen memory)
-----------
32128 bytes total
<NEOchrome Animation> *.ANI
NOTE: To get this feature on versions 0.9 and later select the Grabber
icon and click both mouse buttons in the eye of the second R in the
word GRABBER.
Interestingly enough, some versions of NEO only require you
to press the right button, not both. Hmmm...
1 long magic number BABEEBEA (hex) (seems to be ignored)
1 word width of image in bytes (always divisible by 8)
1 word height of image in scan lines
1 word size of image in bytes + 10 (!)
1 word x coordinate of image (must be divisible by 16) - 1
1 word y coordinate of image - 1
1 word number of frames
1 word animation speed (# vblanks to delay between frames)
1 long reserved; should be zero
--------
22 bytes total for header
? words image data (words of screen memory) for each frame, in
order
<DEGAS> *.PI1 (low resolution)
*.PI2 (medium resolution)
*.PI3 (high resolution)
1 word resolution (0 = low res, 1 = medium res, 2 = high res)
Other bits may be used in the future; use a simple bit
test rather than checking for specific word values.
16 words palette
16000 words picture data (screen memory)
-----------
32034 bytes total
<DEGAS Elite> *.PI1 (low resolution)
*.PI2 (medium resolution)
*.PI3 (high resolution)
1 word resolution (0 = low res, 1 = medium res, 2 = high res)
Other bits may be used in the future; use a simple bit
test rather than checking for specific word values.
16 words palette
16000 words picture data (screen memory)
4 words left color animtion limit table (starting color numbers)
4 words right color animation limit table (ending color numbers)
4 words animation channel direction flag (0 = left, 1 = off, 2 = right)
4 words 128 - animation channel delay in 1/60's of a second. [0 - 128]
(I.e., subtract word from 128 to get 1/60th's of a second.)
-----------
32066 bytes total
<DEGAS Elite (Compressed)> *.PC1 (low resolution)
*.PC2 (medium resolution)
*.PC3 (high resolution)
1 word resolution (same as Degas, but high order bit is set;
i.e., hex 8000 = low res, hex 8001 = medium res,
hex 8002 = high res). Other bits may be used in the
future; use a simple bit test rather than checking
for specific word values.
16 words palette
< 32000 bytes control/data bytes
4 words left color animation limit table (starting color numbers)
4 words right color animation limit table (ending color numbers)
4 words animation channel direction flag [0 = left, 1 = off, 2 = right]
4 words 128 - animation channel delay in 1/60's of a second. [0 - 128]
(I.e., subtract word from 128 to get 1/60th's of a second.)
-----------
< 32066 bytes total
Compression Scheme:
PackBits compression is used (see below). Each scan line is compressed
separately; i.e., all data for a given scan line appears before any data
for the next scan line. The scan lines are specified from top to bottom
(i.e., 0 is first). For each scan line, all the data for a given bit plane
appears before any data for the next higher order bit plane. Note that this
is identical to the IFF 'BODY' image data.
To clarify: The first data in the file will be the data for the lowest
order bit plane of scan line zero, followed by the data for the next higher
order bit plane of scan line zero, etc., until all bit planes have been
specified for scan line zero. The next data in the file will be the data
for the lowest order bit plane of scan line one, followed by the data for
the next higher order bit plane of scan line one, etc., until all bit planes
have been specified for all scan lines.
Caveats:
DEGAS Elite's picture loading routine places some restrictions on
compressed DEGAS files:
o Elite uses a 40-byte buffer to store data being decompressed.
o Whenever a control command is encountered, bytes are stuffed
in this buffer.
o The buffer is only emptied when there are EXACTLY 40
characters in it.
The important conclusion here is that
No control command may cause the buffer to have more than 40
bytes in it. In other words, all control commands must end on
or before the 40-byte boundary.
Any picture violating the last condition will cause Elite to get a bus
error when the picture is loaded.
<Tiny> *.TNY (any resolution)
*.TN1 (low resolution)
*.TN2 (medium resolution)
*.TN3 (high resolution)
Several people have reported sightings of mutated Tiny pictures that
do not follow the standard format, so let's be careful out there. What
is described here is the format that David Mumper's original
TNYSTUFF.PRG produces.
1 byte resolution (same as NEO, but +3 indicates rotation
information also follows)
If resolution > 2 {
1 byte left and right color animation limits. High 4 bits
hold left (start) limit; low 4 bits hold right (end) limit
1 byte direction and speed of color animation (negative value
indicates left, positive indicates right, absolute value
is delay in 1/60's of a second.
1 word color rotation duration (number of iterations)
16 words palette
1 word number of control bytes
1 word number of data words
3-10667 bytes control bytes
1-16000 words data words
-------------
42-32044 bytes total
Control byte meanings:
For a given control byte, x:
x < 0 Absolute value specifies the number of unique words to
take from the data section (from 1 to 127)
x = 0 1 word is taken from the control section which specifies
the number of times to repeat the next data word (from
128 to 32767)
x = 1 1 word is taken from the control section which specifies
the number of unique words to be taken from the data
section (from 128 - 32767)
x > 1 Specifies the number of times to repeat the next word
taken from the data section (from 2 to 127)
Format of expanded data:
The expanded data is not simply screen memory bitmap data; instead, the
data is divided into four sets of vertical columns. (This results in
better compression.) A column consists of one specific word taken
from each scan line, going from top to bottom. For example, column 1
consists of word 1 on scanline 1 followed by word 1 on scanline 2, etc.,
followed by word 1 on scanline 200.
The columns appear in the following order:
1st set contains columns 1, 5, 9, 13, ..., 69, 73, 77 in order
2nd set contains columns 2, 6, 10, 14, ..., 70, 74, 78 in order
3rd set contains columns 3, 7, 11, 15, ..., 71, 75, 79 in order
4th set contains columns 4, 8, 12, 16, ..., 72, 76, 80 in order
Note that Tiny partitions the screen this way regardless of resolution; i.e.,
these aren't bitplanes. For example, medium resoltion only has two bitplanes,
but Tiny still divides medium resolution pictures into four parts.
<Spectrum 512> *.SPU
80 words first scan line of picture (unused) -- should be zeroes
15920 words picture data (screen memory) for scan lines 1 through 199
9552 words 3 palettes for each scan line (the top scan line is
not included because Spectrum 512 can't display it)
-----------
51104 bytes total
Note that the Spectrum 512 mode's three palette changes per scan
line allow more colors on the screen than normally possible, but a
tremendous amount of CPU time is required to maintain the image.
The Spectrum format specifies a palette of 48 colors for each scan line.
To decode a Spectrum picture, one must know which of these 48 colors are
in effect for a given horizontal pixel position.
Given an x-coordinate (from 0 to 319) and a color index (from 0 to 15),
the following C function will return the proper index into the Spectrum
palette (from 0 to 47):
* Given an x-coordinate and a color index, returns the corresponding
* Spectrum palette index.
* by Steve Belczyk; placed in the public domain December, 1990.
FindIndex(x, c)
int x, c;
int x1;
x1 = 10 * c;
if (1 & c) /* If c is odd */
x1 = x1 - 5;
else /* If c is even */
x1 = x1 + 1;
if (x >= x1 && x < x1 + 160)
c = c + 16;
else if (x >= x1 + 160)
c = c + 32;
return c;
<Spectrum 512 (Compressed)> *.SPC
1 word flag word [$5350 or "SP"]
1 word reserved for future use [always 0]
1 long length of data bit map
1 long length of color bit map
<= 32092 bytes compressed data bit map
<= 17910 bytes compressed color bit map
--------------
<= 50014 bytes total
Data compression:
Compression is via a modified run length encoding (RLE) scheme,
similar to DEGAS compressed and Tiny. The data map is stored as a
sequence of records. Each record consists of a header byte followed by
one or more data bytes. The meaning of the header byte is as follows:
For a given header byte, x:
0 <= x <= 127 Use the next x + 1 bytes literally (no repetition)
-128 <= x <= -1 Use the next byte -x + 2 times
The data appears in the following order:
1. Picture data, bit plane 0, scan lines 1 - 199
2. Picture data, bit plane 1, scan lines 1 - 199
3. Picture data, bit plane 2, scan lines 1 - 199
4. Picture data, bit plane 3, scan lines 1 - 199
Decompression of data ends when 31840 data bytes have been used.
Color map compression:
Each 16-word palette is compressed separately. There are three
palettes for each scan line (597 total). The color map is stored as a
sequence of records. Each record starts with a 1-word bit vector which
specifies which of the 16 palette entries are included in the data
following the bit vector (1 = included, 0 = not included). If a palette
entry is not included, it is assumed to be zero (black). The least
significant bit of the bit vector refers to palette entry zero, while the
most significant bit refers to palette entry 15. Bit 15 must be zero,
since Spectrum 512 does not use palette entry 15. Bit 0 should also be
zero, since Spectrum 512 always makes the background color black.
The words specifying the values for the palette entries indicated in
the bit vector follow the bit vector itself, in order (0 - 15).
NOTE: Regarding Spectrum pictures, Shamus McBride reports the following:
"... [The Picture Formats List] says bit 15 of the color map vector
must be zero. I've encountered quite a few files where [bit 15] is
set (with no associated palette entry)..."
<Spectrum 512 (Smooshed)> *.SPS
This format compresses Spectrum 512 pictures better than the standard
method. There are at least two programs that support this format, SPSLIDEX
and ANISPEC, although the two seem to differ slightly in their interpretation
of the format.
One point of interest: Shamus McBride deciphered this format without an ST!
1 word 5350 (hex) ("SP")
1 word 0 (reserved for future use)
1 long length of data bit map
1 long length of color bit map
<= ? bytes compressed data bit map
<= ? bytes compressed color bit map
----------
< ? bytes total
Data compression:
Compression is via a modified run length encoding (RLE) scheme,
similar to that used in Spectrum Compressed (*.SPC) pictures.
The data map is stored as a sequence of records. Each record consists of a
header byte followed by one or more data bytes. The meaning of the header
byte is as follows:
For a given header byte, x (unsigned):
0 <= x <= 127 Use the next byte x + 3 times
128 <= x <= 255 Use the next x - 128 + 1 bytes literally
(no repetition)
There are two kinds of *.SPS files.
The data may appear in the same order as *.SPC files (SPSLIDEX format?):
1. Picture data, bit plane 0, scan lines 1 - 199
2. Picture data, bit plane 1, scan lines 1 - 199
3. Picture data, bit plane 2, scan lines 1 - 199
4. Picture data, bit plane 3, scan lines 1 - 199
The second variant (ANISPEC format?) encodes the data as byte wide vertical
strips:
Picture data, bit plane 0, scan line 1, columns 0 - 7.
Picture data, bit plane 0, scan line 2, columns 0 - 7.
Picture data, bit plane 0, scan line 3, columns 0 - 7.
. . .
Picture data, bit plane 0, scan line 199, columns 0 - 7.
Picture data, bit plane 0, scan line 1, columns 8 - 15.
Picture data, bit plane 0, scan line 2, columns 8 - 15.
. . .
Picture data, bit plane 0, scan line 199, columns 312 - 319.
Picture data, bit plane 1, scan line 1, columns 0 - 7.
. . .
Picture data, bit plane 3, scan line 198, columns 312 - 319
Picture data, bit plane 3, scan line 199, columns 312 - 319.
A for loop to process that data would look like
for (plane = 0; plane < 4; plane++)
for (x = 0; x < 320; x += 8)
for (y = 1; y < 200; y++)
for (x1 = 0; x1 < 8; x1++)
image[y, x + x1] = ...
Color map compression:
Color map compression is similar to *.SPC color map compression, but
the map is compressed as a string of bits, rather than words. There are
597 records (one for each palette). Each record is composed of a 14-bit
header followed by a number of 9-bit palette entries. The 14-bit header
specifies which palette entries follow (1 = included, 0 = not included).
The most significant bit of the header refers to palette entry 1, while
the least significant bit refers to palette 14. Palette entries 0 and 15
are forced to black (zero). Each palette entry is encoded as "rrrgggbbb".
The format of the palette is described above in the section on uncompressed
Spectrum pictures (*.SPU).
<Art Director> *.ART (low resolution only)
16000 words picture data (screen memory)
16 words palette
15 * 16 words 15 more palettes for animation
-------------
32512 bytes total
<C.O.L.R. Object Editor Mural> *.MUR (low resolution only)
16000 words picture data (screen memory)
(palettes are stored in separate files)
-----------
32000 bytes total
<Doodle> *.DOO (high resolution only)
16000 words picture data (screen memory)
-----------
32000 bytes total
<Cyber Paint Sequence> *.SEQ (low resolution only)
This format, while fairly complex, yields excellent compression of animated
images while offering reasonably fast decompression times.
1 word magic number [$FEDB or $FEDC]
1 word version number
1 long number of frames
1 word speed (high byte is vblanks per frame)
118 bytes reserved
---------
128 bytes total for .SEQ header
for each frame {
1 long offset to data for this frame, in bytes [basically useless]
for each frame {
1 word type (ignored?)
1 word resolution [always 0]
16 words palette
12 bytes filename [usually " . "]
1 word color animation limits [not used]
1 word color animation speed and direction [not used]
1 word number of color steps [not used]
1 word x offset for this frame [0 - 319]
1 word y offset for this frame [0 - 199]
1 word width of this frame, in pixels (may be 0, see below)
1 word height of this frame, in pixels (may be 0, see below)
1 byte operation [0 = copy, 1 = exclusive or]
1 byte storage method [0 = uncompressed, 1 = compressed]
1 long length of data in bytes (if the data is compressed, this
will be the size of the compressed data BEFORE decompression)
60 bytes reserved
--------
128 bytes total for frame header
? bytes data
Frames are "delta-compressed," meaning that only the changes from one
frame to the next are stored. On the ST, .SEQ files are always full-screen
low resolution animations, so the sequence resulting from expanding all the
data will be n 320 by 200 pixel low resolution screens, where n is given in
the .SEQ header.
Since only the changes from frame to frame are stored, image data for a
frame will rarely be 320x200 (except for the very first frame, which will
always be a full screen). Instead what is stored is the smallest rectangular
region on the screen that contains all the changes from the previous frame to
the current frame. The x offset and y offset in the frame header determine
where the upper left corner of the "change box" lies, and the width and height
specify the box's size.
Additionally, each "change box" is stored in one of five ways. For each
of these, the screen is assumed to have the full-screen image from the last
frame on it.
o uncompressed copy: The data for this frame is uncompressed image data,
and is simply copied onto the screen at position (x, y) specified
in the frame header.
o uncompressed eor: The data for this frame is exclusive or'ed with the
screen at position (x, y).
o compressed copy: The data for this frame must be decompressed (see
below), and then copied onto the screen at position (x, y) specified
in the frame header.
o compressed eor: The data for this frame must be decompressed (see
below), and then exclusive or'ed with the screen RAM at position (x, y).
o null frame: The width and/or height of this frame is 0, so this
frame is the same as the previous frame.
Of the 5 methods above, the one that results in the smallest amount
of data being stored for a particular is used for that frame.
Compression Scheme:
Compression is similar to that employed by Tiny, but is not quite as
space-efficient.
Control word meanings:
For a given control word, x:
x < 0 Absolute value specifies the number of unique words to
take from the data section (from 1 to 32767).
x > 0 Specifies the number of times to repeat the next word
taken from the data section (from 1 to 32767).
Note that a 0 control word is meaningless.
Format of expanded data:
The expanded data is not simply screen memory bitmap data; instead the four
bitplanes are separated, and the data within each bitplane is presented
vertically instead of horizontally. (This results in better compression.)
To clarify, data for a full screen would appear in the following order:
bitplane 0, word 0, scanline 0
bitplane 0, word 0, scanline 1
...
bitplane 0, word 0, scanline 199
bitplane 0, word 1, scanline 0
bitplane 0, word 1, scanline 1
...
bitplane 0, word 1, scanline 199
...
bitplane 0, word 79, scanline 199
bitplane 1, word 0, scanline 0
...
bitplane 3, word 79, scanline 199
Note however, that the data does not usually refer to an entire screen, but
rather to the smaller "change box," whose size is given in the frame header.
<Animatic Film> *.FLM (low resolution only)
1 word number of frames
16 words palette
1 word speed (0 - 99; value is 99 - # vblanks to delay between frames)
1 word direction (0 = forwards, 1 = backwards)
1 word end action (what to do after the last frame)
0 = pause, then repeat from beginning
1 = immediately repeat from beginning
2 = reverse (change direction)
1 word width of film in pixels
1 word height of film in pixels
1 word Animatic version number (major) [< 2]
1 word Animatic version number (minor)
1 long magic number 27182818 (hex)
3 longs reserved for expansion (should be all zeros)
--------
32 words total for header
? words image data (words of screen memory) for each frame, in order
<Animaster Sprite Bank> *.ASB (low resolution only)
1 word number of frames - 1
1 word ?
1 byte maximum width, in pixels
1 byte maximum height, in pixels
16 words palette
--------
38 bytes total for header
For each frame {
1 word width of this frame (in pixels) - 1
1 word height of this frame (in pixels) - 1
1 word ?
? words image data (words of screen memory)
<STOS> *.MBK
9 words ?
1 long $19861987 (magic number?)
1 long offset from this long to header for low resolution
parameter block (if past end of file, no low res frames)
1 long offset from this long to header for med resolution
parameter block (if past end of file, no med res frames)
1 long offset from this long to header for high resolution
parameter block (if past end of file, no high res frames)
1 word number of low resolution frames
1 word number of medium resolution frames
1 word number of high resolution frames
For each frame {
1 long offset to data (probably only used internally by STOS)
1 byte width in words (multiply by 16 to get width in pixels)
1 byte height in pixels
1 byte X hotspot location
1 byte Y hotspot location
(The format implies other stuff could be here.)
1 long ["PALT" $50414C54]
16 words palette
? words of data for each frame, in the order mentioned in the
header. Monoplanar mask data follows image data for each frame.
----------
? words total
The frames often seem to be in semi-random order, not necessarily in
the order they are to be animated.
<GEM Bit Image> *.IMG
1 word version number of image file [1]
1 word length of header in words [usually 8]
1 word number of color planes [1 for monochrome]
1 word pattern length in bytes [1-8, usually 2 for screen images]
1 word pixel width in microns (1/1000 mm, 25400 microns per inch)
1 word pixel height in microns
1 word line width in pixels
1 word number of lines
-------
? words header length defined in 2nd word of header
? bytes data
NOTES: If the image is a color image (planes > 1), the planes are stored
separately starting with plane 0 -- see the extended .IMG format
description below for details. There is, however, no standard way of
storing the color palette. Some programs may save the palette in separate
files, some may extend the header. For this reason, you should never
assume the header is 8 words long, always get the header length from the
2nd word of the header. Also, the line width in the 7th word is the number
of pixels in a line. Since the data is encoded in byte-wide packets, the
actual unpacked line width is always a multiple of 8, and may be 1-7 pixels
longer than the length specified in the header.
For each byte x in the data section,
x = 0 Pattern/scanline run.
Read the next byte, n (unsigned).
If n > 0 then:
Read a number of bytes equal to the "pattern
length" word in the header. Repeat this
pattern n times.
If n = 0 then:
Scanline run. Data for the next scanline
is to be used multiple times. Read the
following record:
1 byte flag byte [$FF]
1 byte number of times to use
next scanline data
The data for the next scanline follows,
compressed normally.
x = 80 (hex) Uncompressed bit string. The next byte
determines the number of bytes to use
literally. The literal data bytes follow.
otherwise Solid run. The value of x determines
what to draw. The high bit specifies whether
the pixels are set or cleared. A 1 indicates
a byte-run using $FF, a 0 indicates a byte-run
using $00. The low 7 bits, taken as an unsigned
quantity, specify the length of the run in bytes.
<GEM Bit Image, Extended> *.IMG
As mentioned above, there is no completely standard way to store color
images in .IMG files. However, one approach is fairly common, and has
become known as the "XIMG" format.
Though there are many similarities between this and the previous format,
I've given the two formats separate entries to underscore the fact that
assuming a particular encoding of color images in .IMG files is risky.
1 word version number of image file
1 word length of header in words
1 word number of color planes [2, 4, 8, 16, or 24]
1 word pattern length in bytes [1-8, usually 2 for screen images]
1 word pixel width in microns (1/1000 mm, 25400 microns per inch)
1 word pixel height in microns
1 word line width in pixels
1 word number of lines
1 long ["XIMG" $58494D47]
1 word color format [0]
If #planes is 2, 4, or 8, then for each color [there are 2^#planes colors] {
3 words RGB triple for first pen (0...1000, 0...1000, 0...1000)
[This color specification can be passed directly to the
standard vs_color function.]
-------
? words header length defined in 2nd word of header
? bytes data
If the third word specifies that there are 16 or 24 planes, the image data
is true-color rather than palette-based, and the image is separated into
"pseudo-planes" as follows:
16-bit data: 5 red planes, 6 green planes, 5 blue planes
24-bit data: 8 red planes, 8 green planes, 8 blue planes
Note that the pseudo-planes appear *in this order* in the image data.
Color image data is compressed as described above (in the standard .IMG
format), and the image data is stored in the following order:

line 0, plane 0
line 0, plane 1
...
line 0, plane p
line 1, plane 0
...
Note that the scanline run compression is a bit more constrained for color
images -- an entire *scanline* gets repeated, not a single *plane* of a
scanline. In this case, the scanline run header [0, 0, $FF, n] is followed
by the scanline data, in the typical order -- plane 0, plane 1, ... plane p.
NOTE: There is another variant of .IMG that has 'STTT' in place of 'XIMG'.
Chris Ridd says this format is no longer used because it's device
dependent. In any case, we don't have enough examples to properly document
<GEM Metafile> *.GEM
Marcel Boom <[email protected]> recently sent me this
format description. I have reproduced it here, largely unchanged.
The file consists out of a header and the data records. The header has
the following format:
word mf_header: should be -1, which indicates a metafile
word mf_hlength: The length of the header part (usually 24 words)
word mf_version: Version number (usually 101)
word mf_ndcrcfl: 0: NDC coordinates, 2: Raster coordinates
word mf_extends1: Optional, minimal used x coordinate
word mf_extends2: Optional, minimal used y coordinate
word mf_extends3: Optional, maximal used x coordinate
word mf_extends4: Optional, maximal used y coordinate
word mf_width: Optional, page width in 0.1 mm
word mf_height: Optional, page height in 0.1 mm
word mf_coords1: Optional, coordinate system param 1
word mf_coords2: Optional, coordinate system param 2
word mf_coords3: Optional, coordinate system param 3
word mf_coords4: Optional, coordinate system param 4
word mf_imgflag: 0: No images, 1 contains bit images
word mf_reserved1: reserved.
word mf_reserved9: reserved.
After the header follows the data records of the following format:
word 0: VDI command number
word 1: n: Number of parameters for ptsin array
word 2: m: Number of parameters for intin array
word 3: Subopcode
word 4 to 4+n: ptsin array
word 4+n to 4+n+m: intin array
A VDI command number of -1 signals the end of file.
VDI command numbers:
5: Escape functions:
Subopcode:
1: Inquire addressable character cells
2: Exit alpha mode
3: Enter alpha mode
20: Form advance
21: Output window
22: Clear display list
23: Output bit image file
98: Update metafile extents
99: Write metafile item
100: Change GEM VDI filename
6: Polyline
7: Polymarker
8: Text
9: Filled area
11: GDP:
subopcode:
1: Bar
2: Arc
3: Pie
4: Circle
5: Ellipse
6: Elliptical arc
7: Elliptical Pie
8: Rounded rectangle
9: Filled rounded rectangle
10: Jutified graphic text
12: Set character height, absolute mode
13: Set character baseline vector
14: Set color representation
15: Set polyline linetype
16: Set polyline line width
17: Set polyline color index
18: Set polymarker type
19: Set polymarker height
20: Set polymarker color index
21: Set text face
22: Set graphic text color index
23: Set fill interior style
24: Set fill style index
25: Set fill color index
26: Inquire color representation
32: Set writing mode
35: Inquire current polyline attributes
36: Inquire current polymarker attributes
37: Inquire current fill area attributes
38: Inquire current graphic text attributes
39: Set graphic text allignment
102: Extended inquire function
103: Countour fill
104: Set fill perimeter visibility
106: Set graphic text special effects
107: Set character cell height, points mode
108: Set polyline end styles
112: Set user defines fill pattern
113: Set user defined line style pattern
114: Fill rectangle
117: Inquire character cell width
129: Set clipping rectangle
131: Inquire current face information
The meaning of the arrays can be found in the several GEM programming books.
NOTE: The word qualifier is not the Motorola word, but the Intel word,
so high and low byte are swapped!
<STAD> *.PAC (high resolution only)
4 bytes "pM86" (vertically packed) or "pM85" (horizontally packed)
1 byte id byte
1 byte pack byte (most frequently occuring byte in bitmap)
1 byte "special" byte
-------
7 bytes total for header
? bytes data
The data is encoded as follows. For each byte x in the data section:
x = id byte Read one more byte, n. Use pack byte
n + 1 times.
x = "special" byte Read two more bytes, d, and n (in order).
Use byte d n times.
otherwise Use byte x literally.
<Imagic Film/Picture> *.IC1 (low resolution)
*.IC2 (medium resolution)
*.IC3 (high resolution)
4 bytes "IMDC"
1 word resolution (0 = low res, 1 = medium res, 2 = high res)
16 words palette
1 word date (GEMDOS format)
1 word time (GEMDOS format)
8 bytes name of base picture file (for delta compression), or zeroes
1 word length of data (?)
1 long registration number
8 bytes reserved
1 byte compressed? (0 = no, 1 = yes)
If compressed {
1 byte delta-compressed? (-1 = no, > -1 = yes)
1 byte ?
1 byte escape byte
-------
65 bytes total for header (68 bytes if compressed)
? bytes data
Compressed data may be either stand-alone or delta-compressed (relative
to the base picture named in the header). Delta compression involves
storing only how the picture differs from the base picture (i.e., only
portions of the screen that have changed are stored). This is used to
to encode animated sequences efficiently.
Compressed data, stand-alone:
For each byte x in the data section:
x = escape byte Read one more byte, n. (n is unsigned).
If n >= 2, use the next byte n times.
If n = 1, keep reading bytes until a
byte k not equal to 1 is encountered.
Then read the next byte d.
If the number of 1 bytes encountered is o,
use d (256 * o + k) times. I.e.,
if (n == 1) {
o = 0;
while (n == 1) {
o++;
n = next byte;
}
k = n;
d = next byte;
Use d (256 * o + k) times.
}
else {
d = next byte;
Use d (n) times.
}
x != escape byte Use x literally.
Compressed data, delta compressed:
For each byte x in the data section:
x = escape byte Read one more byte, n. (n is unsigned).
If n >= 3, use the next byte n times.
If n = 1, do the same as for n = 1 in
stand-alone compression (above).
If n = 2, then set n = next byte.
If n = 0, end of picture.
If n >= 2, take n bytes from base
picture.
If n = 1, do the same as for n = 1
in stand-alone compression (above),
but take (256 * o + k) bytes from
base picture.
x != escape byte Use x literally.
<IFF Format> *.IFF
4 bytes "FORM" (FORM chunk ID)
1 long length of file that follows
4 bytes "ILBM" (InterLeaved BitMap file ID)
4 bytes "BMHD" (BitMap HeaDer chunk ID)
1 long length of chunk [20]
20 bytes 1 word = image width in pixels
1 word = image height in lines
1 word = image x-offset [usually 0]
1 word = image y-offset [usually 0]
1 byte = # bitplanes
1 byte = mask (0=no, 1=impl., 2=transparent, 3=lasso)
1 byte = compressed [1] or uncompressed [0]
1 byte = unused [0]
1 word = transparent color (for mask=2)
1 byte = x-aspect [5=640x200, 10=320x200/640x400, 20=320x400]
1 byte = y-aspect [11]
1 word = page width (usually the same as image width)
1 word = page height (usually the same as image height)
4 bytes "CMAP" (ColorMAP chunk ID)
1 long length of chunk [3*n where n is the # colors]
3n bytes 3 bytes per RGB color. Each color value is a byte
and the actual color value is left-justified in the
byte such that the most significant bit of the value
is the MSB of the byte. (ie. a color value of 15 ($0F)
is stored as $F0) The bytes are stored in R,G,B order.
4 bytes "CRNG" (Color RaNGe chunk ID)
1 long length of chunk [8]
8 bytes 1 word = reserved [0]
1 word = animation speed (16384 = 60 steps per second)
1 word = active [1] or inactive [0]
1 byte = left/lower color animation limit
1 byte = right/upper color animation limit
4 bytes "CAMG" (Commodore AMiGa viewport mode chunk ID)
1 long length of chunk [4]
1 long viewport mode bits (bit 11 = HAM, bit 3 = interlaced)
4 bytes "BODY" (BODY chunk ID)
1 long length of chunk [# bytes of image data that follow]
? bytes actual image data
NOTES: Some of these chunks may not be present in every IFF file, and may
not be in this order. You should always look for the ID bytes to find a
certain chunk. All chunk IDs are followed by a long value that tells the
size of the chunk (note that "ILBM" is not a chunk ID). This is the number of
bytes that FOLLOW the 4 ID bytes and size longword. The exception to this is
the FORM chunk. The size longword that follows the FORM ID is the size of the
remainder of the file. The FORM chunk must always be the first chunk in an
IFF file.
The R,G,B ranges of AMIGA and ST are different (AMIGA 0...15, ST 0...7),
as is the maximum number of bitplanes (AMIGA: 5, ST: 4).
Format of body data
An expanded picture is simply a bitmap. The packing method is PackBits
(see below), and is identical to MacPaint and DEGAS Elite compressed.
The (decompressed) body data appears in the following order:
line 1 plane 0 ... line 1 plane 1 ... ... line 1 plane m
[line 1 mask (if appropriate)]
line 2 plane 0 ... line 2 plane 1 ... ... line 2 plane m
[line 2 mask (if appropriate)]
...
line x plane 0 ... line x plane 1 ... ... line x plane m
[line x mask (if appropriate)]
The FORM chunk identifies the type of data:
"ILBM" = interleaved bit map
"8SVX" = 8-bit sample voice
"SMUS" = simple music score
"FTXT" = formatted text (Amiga)
<MacPaint> *.MAC
1 long version number [0=ignore header, 2=header valid]
38 * 8 bytes 8x8 brush/fill patterns. Each byte is a pattern row,
and the bytes map the pattern rows top to bottom. The
patterns are stored in the order they appear at the bottom
of the MacPaint screen top to bottom, left to right.
204 bytes unused
-------------
512 bytes total for header
< 51200 bytes compressed bitmap data
-------------
< 51712 bytes total
NOTE: The version number is actually a flag to MacPaint to indicate if
the brush/fill patterns are present in the file. If the version is 0,
the default patterns are used. Therefore you can simply save a MacPaint
file by writing a blank header (512 $00 bytes), followed by the packed
image data.
Bitmap compression:
The bitmap data is for a 576 pixel by 720 pixel monochrome image.
The packing method is PackBits (see below). There are 72 bytes per
scan line. Each bit represents one pixel; 0 = white, 1 = black.
<RGB Intermediate Format> *.RGB (low resolution only)
This format was invented by Lars Michael to facilitate conversions between
standard ST picture formats and higher resolution formats like GIF and IFF.
It supports 12 bits of color resolution by keeping the red, green and blue
components in separate bit planes.
1 word resolution (ignored)
16 word palette (ignored)
16000 words red plane (screen memory)
1 word resolution (ignored)
16 word palette (ignored)
16000 words green plane (screen memory)
1 word resolution (ignored)
16 word palette (ignored)
16000 words blue plane (screen memory)
------------
96102 bytes total
The format was derived by concatenating three DEGAS .PI1 files together --
one for each color gun. The RGB value for a pixel is constructed by looking
at the appropriate pixel in the red plane, green plane, and blue plane. The
bitplanes are in standard ST low resolution screen RAM format, but where pixel
values in screen RAM refer to palette entries (0 through 15), pixel values
here correspond to absolute R, G, and B values. The red, green, and blue
components for each pixel range from 0 to 15 (4 bits), yielding a total of
12 bits of color information per pixel. Not coincidentally, this is exactly
the format of ST palette entries (although on ST's without the extended
palette only the lower 3 bits of each color component are used).
You can view a single bit plane on a standard ST by splitting the .RGB file
into its three DEGAS .PI1 components and setting the palette to successively
brighter shades of gray.
<ComputerEyes Raw Data Format> *.CE1 (low resolution)
*.CE2 (medium resolution)

1 long [$45594553 or "EYES"]
1 word resolution [0 = low res, 1 = medium res]
8 words ?
If resolution = 0 {
64000 bytes red plane, 320 x 200, 1 pixel per byte
64000 bytes green plane, 320 x 200, 1 pixel per byte
64000 bytes blue plane, 320 x 200, 1 pixel per byte
------------
192022 bytes total
else If resolution = 1 {
128000 words 640 x 200, 1 pixel per word
------------
256022 bytes total
This is almost two formats in one:
Low resolution:
The planes are arranged vertically, instead of horizontally.
The first byte is the red component of pixel (0,0), the second is (0,1),
and the third (0,2). The 201st corresponds to (1,0), etc. The 64001st
byte is the green component of (0,0).
Only the low six bits of each byte are used.
Medium resolution:
The picture is arranged vertically, instead of horizontally.
The first word is pixel (0,0), the second is (0,1), and the third
(0,2). The 200th is (1,0) etc.
Each word is divided up into the RGB values for the corresponding
pixel, as follows:
Bit: (MSB) 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 (LSB)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
0 B4 B3 B2 B1 B0 G4 G3 G2 G1 G0 R4 R3 R2 R1 R0
Bit 15 is not used.
<PackBits Compression Algorithm>
The following packing algorithm originated on the Mac, was adopted by
Electronic Arts/Commodore for use in the IFF standard, and then by Tom
Hudson for use in DEGAS Elite. The algorithm is currently used in
MacPaint, IFF, and DEGAS Elite compressed file formats. Each scan line
is packed separately, and packing never extends beyond a scan line.
For a given control byte 'n':
0 <= n <= 127 : use the next n + 1 bytes literally (no repetition).
-127 <= n <= -1 : use the next byte -n + 1 times.
n = -128 : no operation, not used.
-------------------------------------------------------------------------
* Roland Waldi contributed extensive information on the following formats:
GEM, IMG, Doodle, STAD, Imagic Film/Picture, Art Director, IFF
** John Brochu, ST picture formats guru, provided sage advice and many
corrections to the following formats:
NeoChrome, DEGAS Elite Compressed, Spectrum 512 Compressed,
GEM Bit Image, IFF, MacPaint
Version of...........Sun Oct 30 12:40:13 EST 1994
(Last change: Extended GEM .IMG format updated)