"Life is what happens to you while you're busy making plans."
ST PICTURE FILE FORMATS
by David Baggett
(layout modified by RK)
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 Jason Blochowiak John Brochu**
David Brooks Daniel Deimert Neil Forsyth Stefan Hoehn
Gerfried Klein G. "Maddog" Knauss Ken MacLeod Shamus
Jim McCabe Lars Michael Darek Mihocka David Mumper
George Nassas Jim Omura 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
Cyber Studio Delta *.DLT
Animatic Film *.FLM
Animaster Sprite Bank *.ASB
STOS *.MBK
GEM Bit Image *.IMG
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 (most notably 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 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
resolution 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 be 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.
*/
int
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 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 control word of 0 is possible but 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.
<Cyber Studio Delta> *.DLT (low resolution only)
This format's main feature is that it is simple enough to allow
real-time decompression of animated images, while still offering
reasonable compression ratios. Like Cyber Paint .SEQ files, .DLT
files only store the changes from one frame to the next, rather
than the frames themselves. The .DLT format compresses animations
with few frame-to-frame changes best, and will in fact make files
bigger than normal if on average more than half the screen
changes from frame to frame on average.
for each frame {
1 word number of deltas for this frame (0 = end of file)
for each delta {
1 word offset (in bytes) from start of screen RAM where
next data goes
1 long data to be exclusive-or'ed with the screen at the
given offset
}
}
Note: Even if a frame is identical to its predecessor, you
still have to store at least one delta, otherwise the
.DLT reader will assume end of file.
The first screen of a .DLT-encoded sequence is stored in a .PI1
or .PC1 file with the same name.
<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. 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.
<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
This is the version of Monday November 18th 1991.
David Baggett
5640 Vantage Point Road
Columbia, MD 21044
USA
(301) 596-4779
Internet:
dmb@wam.umd.edu
dmb@tis.com
(Please report errors or additions)
Copyright (C) 1988, 1989, 1990, 1991 by David M. Baggett
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.