Skip to main content

 "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.