荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjksam (Linux,c/c++,java), 信区: Program
标  题: THE FLIC file format(English)
发信站: 荔园晨风BBS站 (Wed Nov 28 20:51:03 2001), 转信

The FLIC file format
In this paper, you will find the file format specifications for a class of
animation files that fall in the "FLIC" file category. These include:

FLI files (Autodesk Animator) FLC files (Autodesk Animator Pro)
FLH & FLT files (DTA) CEL files (Autodesk Animator)
FLX files (Tempra Pro, Mathematica Inc.) FLX files (U-Lead, 3DStudio MAX)
Extensions by Pro Motion (Cosmigo) Extensions by EGI (ITB CompuPhase)

The original FLIC file format was described by its author (Jim Kent) in Dr.
Dobb's Journal, March 1993. The original purpose of this document was to
document the modifications and extensions that EGI (a FLIC compiler and player
 engine) adds to the FLIC file format, but since then it has grown to
include all other extensions and variations. As you may not have Jim Kent's
article, all standard file information is included as well.

There are two "official" types of FLIC files: FLI and FLC (the names of
these types refer to the filename extensions). The FLI files are the older
format and are limited to a resolution of 320×200. The FLC file format adds
configurable resolution and better compression.

FLX files are a slight variation on the standard FLC format. Actually, there
are two FLX file formats with slight differences. Both formats use 32768
colours in a packed RGB format (15-bpp, each pixel takes two bytes). The first
 FLX format was defined for "Tempra Pro" by Mathematica Inc. The format used
by 3DStudio MAX (Discreet Inc.) also has the extension FLX but their format is
 more like that of 15-bpp FLH files. Where distinction is needed, this paper
refers to "Tempra FLX" or to "Autodesk FLX" formats (Discreet is affiliated to
 Autodesk).

The FLX file format uses the RLE compression that was originally designed
for 8-bpp FLC files, which is a sub-optimal solution. To improve the
compression and to make the file format more flexible with regard to colour
depth, Dave K. Mason defined new chunk types for his DTA program, in
addition to tagging the new format with a new "type" ID and new extensions
(FLH and FLT) as to avoid confusion. A few other programs, notably EGI, also
support the DTA chunks and type IDs.

CEL files, finally, are actually either FLI or FLC files with a different
extension and one more chunk in the "prefix data" (a kind of optional header).


Overview
A FLIC file stores a number of frames. Every frame contains an image and
possibly a palette, a label, or other data. Usually, a FLIC file contains a
ring frame at the end, so that the animation can be played repeatedly
without a perceptible pause between the last frame and the first (the
unpacking of the first frame, a complete image, is generally slower than a
delta frame update). A FLIC file that contains segments (EGI extension)
optionally contains a ring frame per segment.

FLIC files are structured in a hierarchy of chunks. A chunk contains a fixed
part and a variable part. The fixed part of every chunk contains the type
and the size of the chunk. The rest of the chunk has no fixed format; it all
depends on the chunk type. The purpose of the chunked structure is to allow
new chunks to be added without breaking existing FLIC players. A reader that
does not understand some chunk type can just skip it (using the information
from the fixed part of the chunk). The figure below shows the hierarchy of
chunks in a FLIC file.

All "word" (two bytes) or "double word" (four bytes) values are stored in
Little Endian (this is the byte order used by the Intel 80x86 and Pentium
processor series).

Overview of the FLIC file structure
File header                   general file information

Prefix chunk                  FLC files only
   Cel data chunk             CEL files (identical to FLC files)

Segment table chunk           EGI files only
   Segment chunk              information of every segment, EGI files only
   Label chunk                symbolic names of segments, EGI files only

Huffman table chunk           EGI files only

Script chunk                  EGI files only

Frame chunk
   Postage stamp              icon, FLC files only
      Image data              compressed or uncompressed
   Cel data chunk             EGI files only
   Palette chunk              colour data
   Image data                 compressed in various ways
   Bitmap mask chunk          EGI files only
   Multilevel mask chunk      EGI files only
   Region mask chunk          EGI files only
   Label chunk                EGI files only
   Region chunk               EGI files only
   Wave audio chunk           EGI files only
   User string chunk          EGI files only
   Key palette                EGI files only
   Key image                  EGI files only

Ring frame chunk
   Palette chunk              see above
   Image data                 see above
   Bitmap mask chunk          see above
   Multilevel mask chunk      see above
   Region mask chunk          see above
   Label chunk                see above
   Region chunk               see above
   Wave audio chunk           see above
   User string chunk          see above



The file header
A FLIC file starts with a 128-byte header, see the figure below for a C
structure. The type field contains: 0xAF11 For FLI files
0xAF12 For standard FLC files (with an 8-bit colour depth). FLX files (both
"Tempra FLX" and "Autodesk FLX") also use this header type.
0xAF44 For FLIC files with a colour depth other than 8. The DTA program (by
Dave K. Mason) makes FLIC files with a colour depth of 1, 15, 16 or 24 bits
per pixel. EGI version 3.0 (and later) supports 16-bpp FLIC files.
0xAF30 For FLIC files that use Huffman or BWT compression. These FLIC files
can also have a colour resolution that is different from 8 bits per pixel.
??? Password protected FLIC files have a scrambled type field, so that
previous versions of EGI and other FLIC readers will identify them as
invalid (or unknown) FLIC files.


For FLI files, the delay between two frames is in increments of 1/70 second;
FLC files specify the speed in milliseconds. The header for a FLI file does
not contain the offset of the first and second frames; the first frame is
assumed to start directly behind the file header (no "prefix", "segment table"
 or "Huffman table" chunks) and the offset to the second frame is easily
computed once you read in the header of the first frame. The purpose of
storing the offset to the second frame is that, after playing the ring frame,
 the next frame to display is the second frame of the animation.

Autodesk Animator Pro also stores the MS-DOS formatted date and time stamps of
 the initial creation and last update of the FLIC file, as well as the
serial number of the copy of the Animator Pro program that made/updated the
file (in the creator and updater fields). Other utilities set the creator
field to: 0 Unknown (Pro Motion, DTA, VFD or other)
0x45474900 EGI
0x464c4942 FlicLib
0x42494c46 FlicLib - release 2
0x41544542 Micrografx Simply3D
0x30314c46 Discreet 3DStudio MAX


The frames field in the FLIC file header does not include the ring frame
that loops back to the beginning of the animation.

The flags field is used internally by Autodesk Animator Pro. If a FLIC file is
 written to disk and closed correctly, Animator Pro sets this field to 3.
Several other utilities set it to zero.

The FLIC file header
typedef struct {
  DWORD size;          /* Size of FLIC including this header */
  WORD  type;          /* File type 0xAF11, 0xAF12, 0xAF30, 0xAF44, ... */
  WORD  frames;        /* Number of frames in first segment */
  WORD  width;         /* FLIC width in pixels */
  WORD  height;        /* FLIC height in pixels */
  WORD  depth;         /* Bits per pixel (usually 8) */
  WORD  flags;         /* Set to zero or to three */
  DWORD speed;         /* Delay between frames */
  WORD  reserved1;     /* Set to zero */
  DWORD created;       /* Date of FLIC creation (FLC only) */
  DWORD creator;       /* Serial number or compiler id (FLC only) */
  DWORD updated;       /* Date of FLIC update (FLC only) */
  DWORD updater;       /* Serial number (FLC only), see creator */
  WORD  aspect_dx;     /* Width of square rectangle (FLC only) */
  WORD  aspect_dy;     /* Height of square rectangle (FLC only) */
  WORD  ext_flags;     /* EGI: flags for specific EGI extensions */
  WORD  keyframes;     /* EGI: key-image frequency */
  WORD  totalframes;   /* EGI: total number of frames (segments) */
  DWORD req_memory;    /* EGI: maximum chunk size (uncompressed) */
  WORD  max_regions;   /* EGI: max. number of regions in a CHK_REGION chunk
*/
  WORD  transp_num;    /* EGI: number of transparent levels */
  BYTE  reserved2[24]; /* Set to zero */
  DWORD oframe1;       /* Offset to frame 1 (FLC only) */
  DWORD oframe2;       /* Offset to frame 2 (FLC only) */
  BYTE  reserved3[40]; /* Set to zero */
} FLIC_HEADER;



The modifications that EGI made to the FLIC file header are subtler. Not
only are there a few added fields, but you must also decide whether the fields
 are valid:

First verify that the FLIC file is created by EGI. If the "creator" field of
the FLIC file header is not equal to 0x45474900, the ext_flags field is not
valid.
The ext_flags field indicates what extensions were used. If this value is zero
 (no extensions) the file is a "compatible" FLC file.
    bit    meaning
     0     file contains segments (segment table present)
     1     file contains key images at regular intervals
     2     all frames have an identity palette
     3     file is Huffman compressed
     4     file is BWT-Huffman compressed
     5     bitmap masks are present
     6     multilevel masks are present
     7     region data is present
     8     file is password protected
     9     animation file contains digitized audio
    10     animation file contains a script
    11     region masks are present
If the script contains "segment" instructions, the EGI compiler produces a
segment table. The segment table will come right after the FLIC header. Bit
0 of the "ext_flags" field indicates whether there is a segment table in the
file.
In a segmented file, the "frames" field is set to the number of frames in
the first segment (excluding the optional ring frame). Likewise, the fields
for the offsets to the first and second frames ("oframe1" and "oframe2") are
set to those of the first segment.
The totalframes field is the total number of frames in all segments, including
 all ring frames.
Chunks and subchunks
Every chunk starts with a 6-byte header, that contains the size (four bytes)
and the type (two bytes) for the chunk. All chunks sizes should be rounded
up to an even number of bytes. The values of the main level chunks are above
0xF100, values of the subchunks are below 100 (decimal). As you can see in
figure "Overview of the FLIC file structure", nearly all of the subchunks
appear in the "frame" chunk.

Chunks types are indicated in the FLIC file with a two-byte value, but Jim
Kent's article tagged names on those values (these names appear to be
extracted from the Animator Pro source code). For ease of writing, I use the
same names, in the same glorious ALL UPPER CAPS" that has become common in
discussing the FLIC file format.

Overview of all chunks
   3       CEL_DATA             registration and transparency
   4       COLOR_256            256-level colour palette
   7       DELTA_FLC (FLI_SS2)  delta image, word oriented RLE
  11       COLOR_64             64-level colour palette
  12       DELTA_FLI (FLI_LC)   delta image, byte oriented RLE
  13       BLACK                full black frame (rare)
  15       BYTE_RUN (FLI_BRUN)  full image, byte oriented RLE
  16       FLI_COPY             uncompressed image (rare)
  18       PSTAMP               postage stamp (icon of the first frame)
  25       DTA_BRUN             full image, pixel oriented RLE
  26       DTA_COPY             uncompressed image
  27       DTA_LC               delta image, pixel oriented RLE
  31       LABEL                frame label
  32       BMP_MASK             bitmap mask
  33       MLEV_MASK            multilevel mask
  34       SEGMENT              segment information
  35       KEY_IMAGE            key image, similar to BYTE_RUN / DTA_BRUN
  36       KEY_PAL              key palette, similar to COLOR_256
  37       REGION               region of frame differences
  38       WAVE                 digitized audio
  39       USERSTRING           general purpose user data
  40       RGN_MASK             region mask


  0xF100   PREFIX_TYPE          prefix chunk
  0xF1E0   SCRIPT_CHUNK         embedded "Small" script
  0xF1FA   FRAME_TYPE           frame chunk
  0xF1FB   SEGMENT_TABLE        segment table chunk
  0xF1FC   HUFFMAN_TABLE        Huffman compression table chunk



The rest of the document discusses these chunks and subchunks in detail. On
the right of the caption for each chunk type is the product for which this
chunk is valid. Autodesk Animator is not mentioned explicitly, because there
exist (to my knowledge) no chunks that only Animator supports.


PREFIX_TYPE  all
The prefix chunk contains (undocumented) settings and cel data. It usually
appears in .CEL files.
typedef struct {
  DWORD size;           /* Size of the chunk, including subchunks */
  WORD  type;           /* Chunk type: 0xF100 */
  WORD  chunks;         /* Number of subchunks */
  BYTE  reserved[8];    /* Reserved, set to 0 */
} PREFIX_HDR;

CEL_DATA  all, EGI 3+

typedef struct {
  DWORD size;           /* Size of the chunk, always 64 */
  WORD  type;           /* Chunk type: 3 */
  short center_x;       /* coordinates of the cel centre or origin */
  short center_y;
  WORD  stretch_x;      /* stretch amounts */
  WORD  stretch_y;
  WORD  rot_x;          /* rotation in x-axis (always 0) */
  WORD  rot_y;          /* rotation in y-axis (always 0) */
  WORD  rot_z;          /* z-axis rotation, 0-5760=0-360 degrees */
  WORD  cur_frame;      /* current frame in cel file */
  BYTE  reserved1[2];   /* Reserved, set to 0 */
  WORD  transparent;    /* Transparent colour index */
  BYTE  reserved2[38]   /* Reserved, set to 0 */
} CEL_DATA;
The CEL_DATA chunk is usually not present in FLC files. Intermediate files
used by Autodesk Animator Pro with the .CEL extension usually contain a
CEL_DATA in the prefix chunk. The CEL files have the same format as FLC files.


EGI version 3.0 may generate CEL_DATA chunks inside normal frames; i.e.
outside the prefix chunk. EGI uses the CEL_DATA chunk to hold the origin of
the frame. Sprite animation toolkits can use the origin of a frame for
run-time "registration" of the frame. (Registration is a term that animators
use to mean the correct positioning of a frame in relation to the other frames
 and to the background image.)

EGI uses only the center_x and center_y fields of the structure. The
center_x field gives the horizontal offset of the origin relative to the
left edge of the frame. The center_y field is the vertical offset of the
origin relative to the top edge, where a positive value points downwards.


SCRIPT_CHUNK  EGI 3+

EGI supports embedded run-time scripts in FLIC files that are written in the
"Small" language (see http://www.compuphase.com/small.htm). The compiled
P-code is added to the FLIC file. The format of the compiled P-code and an
instruction reference can be found in the Small manual (available on-line as a
 PDF document on the Small language page mentioned earlier).

Specific functions in the run-time script execute on "events" in the FLIC
animation, such as reaching the last frame of the segment (this is the frame
before the ring frame). The currently defined event functions are:

  @FlicClose()            Called when the animation is closed.
  @FlicFrame()            Called after each frame is decoded.
  @FlicLabel()            Called when a label was reached.
  @FlicLastFrame()        Called when the animation reaches its last frame
                          of the current segment.
  @FlicLButtonDown(x, y)  Called when the left mouse button is pressed in
the
                          animated frame.
  @FlicLButtonUp(x, y)    Called when the left mouse button is released in
the
                          animated frame.
  @FlicOpen()             Called when the animation is opened.
  @FlicPlay()             Called when the animation is starts playing.
  @FlicStop()             Called when the animation is stopped explicitly.


SEGMENT_TABLE  EGI 1+

typedef struct {
  DWORD size;          /* Size of this chunk, including subchunks */
  WORD  type;          /* Chunk type: 0xF1FB */
  WORD  segments;      /* Number of SEGMENT chunks that follow */
} SEGMENT_TABLE;
If a segment table is present, it overrules the values in the header (number
of frames, offsets to the first and second frames).


SEGMENT  EGI 1+

typedef struct {
  DWORD size;          /* Size of this chunk (always 32 bytes) */
  WORD  type;          /* Subchunk type: 34 */
  WORD  label;         /* Label of the segment (user value) */
  BYTE  reserved1[2];  /* Reserved, set to zero */
  WORD  cont_image;    /* "continued from" image id */
  WORD  last_image;    /* id of the last image of this segment */
  WORD  flags;         /* Flags */
  WORD  frames;        /* Number of frames in the segment */
  DWORD oframe1;       /* File offset to frame 1 of the segment */
  DWORD oframe2;       /* File offset to frame 2 */
  WORD  next_segment;  /* segment number of segment to proceed with */
  WORD  repeat;        /* repeat count (0=indefinitely) */
  BYTE  reserved2[2];  /* Reserved, set to zero */
} SEGMENT;
The flags field contains four bit flags:

    bit    meaning
     0     the segment contains a ring frame
     1     the first frame contains a full image
     2     the "next_segment" field of the structure is valid
     3     audio must be synchronized with the animation
If bit 1 is set, the first frame contains either a full image, or a delta
image plus a key image. In other words, bit 1 indicates whether the segment is
 a "launch point". See the EGI compiler instruction launch_point for more
details.

The frames field does not include the ring frame (if a ring frame is present).


In a FLIC file has multiple segments and some of the segments are
"continued" from other segments (see the compiler instruction continued_from),
 a frame may contain both a full image (the key image) and a delta image.
The EGI player uses the cont_image and last_image fields to determine
whether it can use the delta image (whose decoding is usually quicker than a
full image), or whether it must decode the full image instead.

When creating the FLIC file, the EGI compiler assigns each picture a unique
number. It stores the number of the last image in a segment in the
last_image field of the SEGMENT structure. When you add a continued_from
instruction to the segment, the compiler copies the last_image field of the
segment that was specified in the continued_from instruction to the cont_image
 field of the current segment. The compiler then proceeds to create a delta
image given the first image of the current segment and the last image of the
"continued from" segment. A segment that is not continued from another segment
 has a value of 0xFFFF in the cont_image field.

The EGI player goes the opposite route. Assuming that the player just
displayed the last frame of a segment, and at that moment you switch to
another segment: if the last_image field of the current segment is the same as
 the cont_image of the next field, the player decodes the delta image of the
new segment. Otherwise it decodes the key image.


HUFFMAN_TABLE  EGI 1+

typedef struct {
  DWORD size;          /* Size of this chunk */
  WORD  type;          /* Chunk type: 0xF1FC */
  WORD  codelength;    /* Maximum length of the Huffman codes */
  WORD  numcodes;      /* The number of codes */
  BYTE  reserved[6];   /* Must be set to zero */
  /* The following three fields are repeated "numcodes" times */
  WORD  code;          /* Huffman code */
  BYTE  length;        /* Length of the Huffman code */
  BYTE  value;         /* Byte value represented by the Huffman code */
} HUFFMAN_TABLE;
See the "Compression" paper for information on the Huffman compression
algorithm. This chunk is only present if bit 3 of the ext_flags of the FLIC
file header is set.


FRAME_TYPE  all

This chunk is defined by Autodesk Animator, but Pro Motion and EGI extend it.


typedef struct {
  DWORD size;          /* Size of the chunk, including subchunks */
  WORD  type;          /* Chunk type: 0xF1FA */
  WORD  chunks;        /* Number of subchunks */
  WORD  delay;         /* Delay in milliseconds */
  BYTE  reserved[6];   /* Reserved, set to 0 */
} FRAME_TYPE;
The delay value overrules the speed field in the FLIC header; a value of
zero indicates that the normal speed (from the FLIC header) applies. The delay
 field is an extension to the FLIC format, introduced by Cosmigo's Pro Motion.



COLOR_256 and COLOR_64  all

The two subchunks with types 4 and 11 are identical, except that the range
of the RGB values is 0-63 for COLOR_64 (type 11) and 0-255 for COLOR_256 (type
 4).

The data in the chunk is organized in packets. The first word following the
chunk header is the number of packets in the chunk. Each packet consists of
a 1-byte skip count, a 1-byte copy count and a series of 3-byte RGB values
(the "copy count" gives the number of RGB triplets). If the copy count is
zero, there are 256 RGB triplets in the packet. For example, the data to
change colours 2, 7, 8 and 9 would appear as:

    2                           /* two packets */
    2,1,r,g,b                   /* skip 2 entries, change 1 entry */
    4,3,r,g,b,r,g,b,r,g,b       /* skip 4, change 3 */


BLACK  all

All pixels in the frame have colour 0. This chunk has no data following the
chunk header.


FLI_COPY  all

The data that follows the chunk header are the pixels of an uncompressed image
 of the frame. The number of pixels are exactly width×height of the frame.
The first pixel is for the upper left corner of the frame.

Note that FLX files (15-bpp) use 2 bytes per pixel.


BYTE_RUN (FLI_BRUN)  all

The data following the chunk header is a full image that is compressed with
byte oriented RLE. The first image of a segment and key frames are usually
stored in a BYTE_RUN chunk.

Each line of the image is compressed separately, starting from the top of
the image. The first byte of each line is the packet count. It is a holdover
from the FLI format and it should be ignored, because it is now possible to
have more than 255 packets on a line (for FLC files). Instead, the width of
the frame image now is the criterion for decoding: continue decompressing
until the number of uncompressed pixels becomes equal to the image width.
However, some players still rely on this packt count, so FLIC compilers should
 still generate them and only set it to zero when the packet count indeed does
 exceed 255.

Each RLE packet consists of a count byte and one or more data bytes. If the
count byte is negative, its absolute value is the number of data bytes
(following the count byte) to copy to the image: a literal run. If the count
byte is positive, the single data byte that follows must be replicated in
the image "count" times: a replicate run.


DELTA_FLI (FLI_LC)  all

This chunk is used for FLI type files; the newer FLC format replaces this
chunk with DELTA_FLC (see below). The chunk contains the differences (the
"delta") between the current frame and the previous frame.

The first 16-bit word behind the chunk header is the line number (starting
from the top of the image) for the first line in the image that differs from
the previous frame. In other words, it is a line skip count. The second word
is the number of lines in the chunk. The data for the lines themselves
follow these two words.

Each line starts with a one-byte packet count for the line. Unlike the
BYTE_RUN chunk, this value is significant because the "delta" need not to
store the complete width of the frame image. The packets themselves follow the
 packet count. Each packet consists of a column skip count, an RLE count
byte and zero or more data bytes. The column skip count is a one-byte value;
it holds the number of pixels to skip (the number of pixels that did not
change between the current frame and the previous frame) from the current
position in the line. It can have a value of zero. The RLE count byte and
the data bytes are similar to the BYTE_RUN encoding: if the count is positive,
 that number of bytes is to be copied from the data to the image (literal
run); if the count is negative, its absolute value is the replication count of
 the one data byte that follows (replicate run).

Two pitfalls:

The negative/positive meaning of the RLE count byte is reversed from that of
the BYTE_RUN encoding.
The RLE count byte can be zero. This occurs when the number of pixels to
skip is more than 255. In this case, skip count is split over two packets. The
 first of these contains a skip count of 255, a RLE count of 0, and no data
following the RLE count. The skip count of the second packet holds the
remaining number of pixels to skip.
Also note that the "FLIC file format" document that originates from Autodesk
mentions an extra byte that prefixes each line. This byte, the "starting x
position of the data on a line", does not exist.


DELTA_FLC (FLI_SS2)  all

This chunk is similar to the DELTA_FLI chunk, but it compresses the delta
image differently. The data following the chunk header is organized into lines
 and each line is organized into packets. Every line starts with one or more
word-sized "opcodes".

The first word following the chunk header is the number of lines in the chunk.
 This count does not include "skipped" lines. Each line starts with one or
more opcodes. One of the opcodes (the last) is the packet count. The highest
two bits of the opcode word give its type:

  Bit 15   Bit 14   Description
    0        0      The opcode is the packet count for the line, it can be
zero
    0        1      Undefined
    1        0      Store the opcode's low byte (bits 0-7) in the last pixel
of the line
    1        1      The absolute value of the opcode is the line skip count
The RLE compression of DELTA_FLC is similar to that of DELTA_FLI, but it is
word oriented. The first byte of each packet is the column skip count; the
second byte is the RLE count byte. Zero or more data words follow the RLE
count byte. If the count is positive, that number of words of data is copied
to the image; if the count is negative, one data word follows and the absolute
 value of the count tells how many times that word must be replicated in the
image.

The two pitfalls from the DELTA_FLI chunk apply here too (see above).
Additionally:

The packet count for a line can be zero. This occurs when the frame image
has an odd width and only the last pixel of a line changes. In that case,
there is a "last byte" opcode for the line, but no further packets.
For "Autodesk FLX" files, the skip count of each packet should be considered
the number of "pixels" to skip, not bytes. For "Tempra FLX" files, the skip
count is the number of bytes (and it therefore should always be an even
value).

PSTAMP  all

typedef struct {
  DWORD size;           /* Size of this chunk */
  WORD  type;           /* Chunk type: 18 */
  WORD  height;         /* Height of the postage stamp */
  WORD  width;          /* Width of the postage stamp */
  WORD  xlate;          /* Colour translation, always 1 */
} PSTAMP;
A "postage stamp" is a reduced image of the first frame of an animation. A
postage stamp created by Autodesk Animator Pro has the preferred size of
100*63 (the actual size can vary) and uses a universal palette.

The palette is an RGB cube with 6 levels of each red, green and blue. This
totals in 216 colours. An arbitrary RGB value (where each component is in
the range of 0-255) is mapped into the six-cube space using:


((6*red)/256) * 36 + ((6*green)/256) * 6 + (6*blue)/256
The PSTAMP chunk embeds another chunk. This is usually a BYTE_RUN chunk or a
FLI_COPY chunk (for compressed and uncompressed images respectively). If the
type of the embedded chunk is 18 again (the type of PSTAMP is also 18), that
chunk contains a 256-byte colour translation table. The translation table maps
 every palette index of the first frame to the universal six-cube colour
space. To display the postage stamp, a program decodes the image of the
first frame and maps every pixel of that image to the six-cube colour
palette (using the translation table).


DTA_BRUN, DTA_COPY and DTA_LC  DTA, EGI 3+

These chunks are generated by the DTA program by Dave K. Mason for FLIC
files with 15-bit, 16-bit or 24-bit colour depth, and by EGI starting with
version 3.0. FLIC files with these formats usually have a .FLH or a .FLT
extension. EGI supports only the 16-bit variety of these chunks.

In 24-bit FLIC files, pixels are made up of three bytes in the order B,G,R. In
 16-bit files the colour values are packed into words (two-byte units) in
"rrrrrggg gggbbbbb" format. 15-Bit FLIC files have pixels packed into the
format "0rrrrrgg gggbbbbb". (The "blue" bits are in the lowest bit positions
of each word.)

The DTA_BRUN chunk is numbered 25 (instead of 15 for a standard BYTE_RUN). The
 Repeat/Copy value is still a byte, but it refers to a number of pixels to
copy or repeat, not bytes.

The DTA_LC chunk is numbered 27. Internally it is like chunk type 7
(DELTA_FLC). It starts with a number-of-lines value. For each line, the packet
 is a signed word value. If it is negative then it represents a
lines-to-skip value and it does not count toward the number-of-lines. Each
non-negative packet begins with a skip counter. This is still a byte, but it
represents a number of pixels to skip, not bytes. Next comes a repeat/copy
packet. It represents a number of pixels to copy or skip, not words. (Though
in a 16-bit FLIC file, the pixels are words.)

The copy chunk is numbered 26, although the standard "copy" chunk type 16
(FLI_COPY) would do equally well: there is no decoding for copy chunks.


LABEL  EGI 1+, EGI 3.3

typedef struct {
  DWORD size;           /* Size of this chunk (usually 10) */
  WORD  type;           /* Chunk type: 31 */
  WORD  label           /* Label of the frame (user value) */
  BYTE  reserved[2]     /* Reserved, set to zero */
} LABEL;


The EGI API function FlicPlay() sends a notification message if it
encounters a label subchunk in a frame. The message is sent (using either
the Microsoft Windows function SendMessage() or using a direct callback) after
 decoding (and displaying) the frame. If the FLIC file has an embedded script,
 a label invokes the public function @FlicLabel() in the script.


KEY_IMAGE  EGI 1+

For standard 256-colour FLIC files, the KEY_IMAGE chunk is the same as
BYTE_RUN, but a frame that has a KEY_IMAGE chunk also contains a DELTA_FLC
from a previous segment. A player can decide (based on the transition it makes
 from segment to segment) whether to decode the KEY_IMAGE and skip the
DELTA_FLC, or to decode the DELTA_FLC and skip the KEY_IMAGE. See the
SEGMENT chunk for more information.

For 16-bit FLIC files, the KEY_IMAGE chunk has the same encoding as DTA_BRUN.
 Similarly to the 256-colour FLIC files, the KEY_IMAGE chunk only appears in
combination with a DTA_LC chunk.


KEY_PAL  EGI 1+

The same as COLOR_256, but it is only present for key images.


BMP_MASK and MLEV_MASK  EGI 1+ and EGI 2+

The chunk MLEV_MASK is defined as of EGI version 2.0; the chunk BMP_MASK
exists since EGI 1.0.

The chunk starts (right after the chunk header) with four 16-bit words that
give the bounding box of the mask. You can use this bounding box to speed up
drawing operations, because you do not have to draw anything outside this
box (all pixels are transparent outside the bounding box). The values are
stored in the following order: x y width height.

The mask data starts behind the bounding box. Each line is encoded separately.
 A line starts with a "line skip count", which indicates how many lines remain
 unchanged from the previous mask. It is a two-byte value. It is zero for
every line in a full mask.

The bitmap data (for the mask bitmap) comes after the line skip count. The
bitmap data is compressed with the same RLE encoding as the BYTE_RUN image.
This means that if the first (type) byte is positive, it is followed by a
single pixel that must be replicated; if it is negative, it is followed by a
series of bytes that must be copied literally. In contrast to the BYTE_RUN
compression, no "packet count" byte is stored at the beginning of a scan line.
 Each scan line of the mask is compressed individually. Huffman and BWT
compression do not apply to masks.

The data of a bitmap mask (after compression) is a 1 bit per pixel (8 pixels
per byte) bitmap with the same size as the frame image. Each bit that is set
("1") represents a transparent pixel in the frame image. Each bit that is
cleared ("0") represents an opaque pixel.

A multilevel mask is an 8 bits per pixel bitmap (with the same size as the
frame image). Each byte in the mask represents the transparency level of the
corresponding pixel in the frame image. A value of 255 is fully transparent,
and 0 is fully opaque. In EGI version 2.x, you could actually use only two
levels (0 and 255); as of EGI version 3.0, you can define up to 15
additional transparency levels.

Note that you can only specify the number of transparency levels; the
opacity value of each level of the multilevel masks is not stored. The FLIC
file format does not indicate the purpose the additional mask levels either.
The number of transparency levels is in the transp_num field in the FLIC
file header (EGI versions prior to 3.0 set this field to zero). The multilevel
 transparency masks were designed to be used with AniSprite, which allows
you to set the opacity for each level (and lets you decide whether the
additional levels are for "luma" masks or for "alpha" masks); please look up
the AniSprite documentation for more information.

A frame can contain both a full image and a delta image. This occurs, for
example when a segment in a FLIC file is both "continued_from" another segment
 and a launch point, or when the "key_frames" instruction is used. The mask
for a frame that contains both a delta image and a full image is always a full
 mask.

See also the RGN_MASK chunk.


REGION  EGI 1+

typedef struct {
  DWORD size;           /* Size of this chunk */
  WORD  type;           /* Chunk type: 37 */
  WORD  number;         /* Number of rectangles that form the region */
  /* The following four fields are repeated "number" times */
  WORD  x;              /* Pixel coordinates of a rectangle */
  WORD  y;
  WORD  width;          /* Size of the region in pixels */
  WORD  height;
} REGION;
The EGI compiler stores the region of frame differences (see the dif_region
instruction of the compiler's script language) by means of a grid. In the
current release, the grid is composed of square tiles of 16*16 pixels. When
a single pixel in a tile changes, all 256 pixels in that tile are flagged as
"modified".

Two neighbouring tiles that are both flagged as "modified" are combined into a
 single new tile. The edges of the resulting rectangular tiles are always
snapped to the grid points. Therefore, each rectangle in a region of frame
differences needs not to enclose the object at pixel precision. However, no
rectangle will exceed the bounding box of all differences between two frames.


The purpose of a coarse grid is to avoid a large amount of very small areas.
The cost of the overhead for every call to the BitBlt() function for all these
 areas might be higher than the cost of blitting several pixels too many.

As of EGI version 2.0, the maximum number of tiles in a region is in the field
 max_regions in the FLIC file header.


WAVE  EGI 2+

typedef struct {
  DWORD size;          /* size of this chunk */
  WORD  type;          /* Chunk type: 38 */
  WORD  flags;
  WORD  samplefreq;    /* sample frequency */
  DWORD overlap;       /* sample overlap (in bytes) */
  BYTE  reserved[6];   /* always zero */
} WAVE;
The flags value is a bit field.

  Bit  Description

------------------------------------------------------------------------------
--

   0   Sample size is 16-bit (otherwise 8-bit)
   1   Format is signed PCM (otherwise unsigned PCM)
   2   Audio is stereo
   3   First block of the audio stream (open/reset sound card/driver)
   4   Last block of the audio stream (close sound card/driver)
The digitized audio data follows the chunk. The format depends on the
various flags. If audio is 16-bit, there are two bytes per sample, in Little
Endian (Intel format). In unsigned PCM, the "silence" level is 128 for 8-bit
samples and 32768 for 16-bit samples. For stereo audio the samples for the
left and right channels are interleaved; the sample for the left channel
precedes the sample for the right channel.

Currently, EGI only supports 8-bit unsigned PCM or 16-bit signed PCM. These
are the same formats as used in the .WAV and the .VOC file formats.

An audio stream is often be stored in a single block. The audio starts at
the frame in which the block occurs, and it continues to "sound" during the
displaying of the next frames. Audio and animation are not necessarily
synchronized. For these single block audio streams, both bits 3 and 4 in the
flags field are set, and overlap is always zero.

The audio stream can also be cut in various blocks. The first block contains
enough samples to get from the current frame to the first key frame. The key
frame contains another audio block with enough samples to get to the next
key frame, etc. Here, the bits 3 and 4 of the flags field help to glue the
blocks together to a sequential audio stream. Audio and animation should be
synchronized to play back correctly. (The EGI player synchronizes animation
and sound by default if the sound is cut into blocks.)

To avoid gaps in the audio when synchronization is not perfect, each block
contains more samples than strictly necessary. In the current implementation,
 EGI adds enough samples to go to one frame after each key frame. When sending
 a (next) block to the audio device, you should ignore the first overlap bytes
 from the audio data.

You can jump in the middle of an animation, and this way, you can also jump in
 the middle of a multiple block audio stream. In this case, to get a proper
synchronization, ignore the overlap field for the first audio block that you
encounter.


USERSTRING  EGI 2+

A zero-terminated ASCII string follows the chunk header. The USERSTRING
chunk allows an application to store general-purpose strings (both for
copyright information as for references to other files or data) in a frame.


RGN_MASK  EGI 3.1+

The chunk starts (right after the chunk header) with four 16-bit words that
give the bounding box of the mask (this is similar to the BMP_MASK and
RGN_MASK chunks). The values are stored in the following order: x y width
height.

The mask data starts behind the bounding box and consists of a list of
non-overlapping rectangles. This set of rectangles describes the opaque region
 of the frame. Each rectangle is composed of four 16-bit words, again in the
order x y width height. The number of rectangles in the region can be
determined from the size of the chunk.

There is no delta encoding for a region mask, except that if a RGN_MASK
chunk is absent from a frame it should be considered equal to the region
mask of the previous frame.

Note that the REGION chunk contains a coarse region of changes between two
frames. The RGN_MASK chunk is a region of opaque areas of a single frame and
it is precise at pixel level.

See also the BMP_MASK and MLEV_MASK chunks.





Frequent errors
Unfortunately, several utilities create FLIC files that do not completely
comply with the standard. Most FLIC players attempt to detect and silently
correct these errors. Below is a list of frequent errors in FLIC files.

The colour depth is set to zero. The colour depth must usually be 8. DTA and
EGI (starting with version 3.0) support FLIC files with a different colour
depth and use a different "type" value in the FLIC file header. FLX files
(15-bpp FLC files that use the same chunks as for 8-bpp FLC files) should have
 the value 16 in the header field for the colour depth, even though they are
actually 15-bpp.
The offsets to the first and second frames are zero in an FLC file. In fact,
it appears that these are FLI files with a FLC header.
The offset to the second frame is set to an incorrect value. I have seen
FLIC files where the offset to the second frame was set to zero, to the offset
 to the first frame, to the offset to the ring frame, or to a seemingly random
 value.
DELTA_FLC chunks are present in files with a FLI header. Since most players
are combined FLI/FLC players, this is usually not a problem. However, a FLIC
file with DELTA_FLC chunks should have a FLC header.
Chunk sizes are not rounded to an even number of bytes. Only very few FLIC
players have problems with frames with an odd number of bytes, but it goes
against the "standard".
The sizes of all sub-chunks in a frame chunk do not add together to the size
in the frame chunk header. Sometimes the frame chunk appears to be padded with
 extra data behind the last frame. Sometimes the size a subchunk is
incorrect (I have seen this with the FLI_COPY chunk).
Garbage in reserved fields of a chunk or of the header. Reserved fields in a
chunk should be set to zero. Otherwise, the chunks become difficult to extend.
 Players must do their best in estimating (or guessing) whether a field is a
valid value for a chunk extension or whether it is garbage.
DELTA_FLC chunks with a "line count" of zero. This is essentially an 8-byte
chunk: 6 bytes for the chunk header and two bytes for the count of lines in
the chunk. Since this count is zero, no lines with compressed data follows.
Although this is (or should be) valid, the AAPLAY engine crashes when it
encounters such blocks. Therefore, utilities should avoid creating these
chunks.
DELTA_FLI is not documented correctly. The document that originates from
Autodesk and which was published with small modifications in Dr. Dobb's
Journal (see below), claims that:
"Each line begins with two bytes. The first byte contains the starting x
position of the data on the line, and the second byte the number of packets
for the line."
However, as this paper describes correctly, each line starts with only one
byte, which is the number of packets for the line.


References
Kent, J.; "The FLIC File format"; Dr. Dobb's Journal, March 1996 (Volume 18,
issue 3).



? ITB CompuPhase, 1997-2001, The Netherlands
http://www.compuphase.com

--
   mm       ☆__      __  __ __☆______ ______ __  __☆
/^(  )^\      █      █  █/    █____ █__█ █∨█
\,(..),/  ▅__█  ▅__█  █\__  ▂__█ █  █ █  █
  V~~V   ▇▆▅▃▁I'm a bat. I'm very bad!^Q^_▃▄▆▇你好!^_^欢迎大家到linux?

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店