2007-09-18 23:57:02 +00:00
|
|
|
ASE Files (.ASE) Format description
|
2009-01-24 00:41:01 +00:00
|
|
|
Copyright (C) 2004-2009 by David Capello
|
2007-09-18 23:57:02 +00:00
|
|
|
----------------------------------------------------------------------
|
|
|
|
|
|
|
|
1. References
|
|
|
|
2. Introduction
|
|
|
|
3. Header
|
|
|
|
4. Frames
|
|
|
|
5. New chunk types
|
|
|
|
6. File Format Changes
|
|
|
|
|
|
|
|
========================================
|
|
|
|
1. References
|
|
|
|
========================================
|
|
|
|
|
|
|
|
ASE files use Intel (little-endian) byte order.
|
|
|
|
|
|
|
|
BYTE An 8-bit unsigned integer value
|
|
|
|
WORD A 16-bit unsigned integer value
|
|
|
|
DWORD A 32-bit unsigned integer value
|
|
|
|
LONG A 32-bit signed integer value
|
|
|
|
BYTE[n] "n" bytes.
|
|
|
|
RECT Four LONGs (in the order: x-pos, y-pos, width, heigth)
|
|
|
|
STRING length=WORD (how many characters to read next)
|
|
|
|
string=BYTE[length]
|
|
|
|
The \0 character isn't included.
|
2010-03-28 19:18:15 +00:00
|
|
|
PIXEL Pixel format:
|
|
|
|
- In RGB images, each pixel have 4 bytes in
|
|
|
|
this order Red, Green, Blue, Alpha.
|
|
|
|
- In Grayscale images, each pixel have 2 bytes
|
|
|
|
in the order Value, Alpha.
|
|
|
|
- In Indexed images, each pixel uses 1 byte (the index).
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
========================================
|
|
|
|
2. Introduction
|
|
|
|
========================================
|
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
The format is much like FLI/FLC files, but with different magic number
|
|
|
|
and differents chunks. Also, the color depth can be 8, 16 or 32 for
|
|
|
|
Indexed, Grayscale and RGB respectively, and the images are more easy
|
|
|
|
to read (there aren't differences with old frames). The palette isn't
|
|
|
|
included for color depths more than 8, but when the sprite is 8 bpp,
|
2008-03-22 18:43:56 +00:00
|
|
|
the palette is in a FLI color chunk (it could be type=11 or type=4).
|
|
|
|
See fli.txt for details.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
To read the sprite, just do this:
|
|
|
|
* Read the ASE header (section 3)
|
|
|
|
* For each frame do (how many frames? the ASE header has that
|
|
|
|
information):
|
|
|
|
+ Read the frame header (section 4)
|
|
|
|
+ For each chunk in this frame (how many chunks? the frame header
|
|
|
|
has that information)
|
|
|
|
- Read the chunk (it should be layer information, a cel or a
|
|
|
|
palette)
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
========================================
|
|
|
|
3. Header
|
|
|
|
========================================
|
|
|
|
|
|
|
|
A 128-byte header (same as FLC/FLI header, but with other magic
|
|
|
|
number):
|
|
|
|
|
|
|
|
DWORD File size
|
|
|
|
WORD Magic number (0xA5E0)
|
|
|
|
WORD Frames
|
|
|
|
WORD Width in pixels
|
|
|
|
WORD Height in pixels
|
|
|
|
WORD Color depth (bits per pixel)
|
2007-12-05 01:30:50 +00:00
|
|
|
32 bpp = RGBA
|
|
|
|
16 bpp = Grayscale
|
|
|
|
8 bpp = Indexed
|
2007-09-18 23:57:02 +00:00
|
|
|
DWORD Flags (must be 0)
|
|
|
|
WORD Speed (milliseconds between frame, like in FLC files)
|
2008-03-27 14:29:33 +00:00
|
|
|
DEPRECATED: You should use the frame duration
|
|
|
|
field from each frame header
|
2007-09-18 23:57:02 +00:00
|
|
|
DWORD Set be 0
|
|
|
|
DWORD Set be 0
|
2010-03-28 19:17:51 +00:00
|
|
|
DWORD Ignore this field
|
2010-03-28 15:15:32 +00:00
|
|
|
WORD Number of colors (0 means 256 for old sprites)
|
2010-03-28 19:17:51 +00:00
|
|
|
BYTE[94] For future (set to zero)
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
========================================
|
|
|
|
4. Frames
|
|
|
|
========================================
|
|
|
|
|
|
|
|
After the header come the "frames" data. Each frame has this little
|
|
|
|
header of 16 bytes:
|
|
|
|
|
|
|
|
DWORD Bytes in this frame
|
|
|
|
WORD Magic number (always 0xF1FA)
|
2007-11-16 20:49:40 +00:00
|
|
|
WORD Number of "chunks" in this frame
|
2008-03-27 14:29:33 +00:00
|
|
|
WORD Frame duration (in milliseconds)
|
2007-09-18 23:57:02 +00:00
|
|
|
BYTE[6] For future (set to zero)
|
|
|
|
|
|
|
|
Then each chunk format is:
|
|
|
|
|
|
|
|
DWORD Chunk size
|
|
|
|
WORD Chunk type
|
|
|
|
BYTE[] Chunk data
|
|
|
|
|
|
|
|
|
|
|
|
========================================
|
|
|
|
5. New chunk types
|
|
|
|
========================================
|
|
|
|
|
|
|
|
Layer Chunk (0x2004)
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
In the first frame should be a set of layer chunks to determine the
|
|
|
|
entire layers layout:
|
|
|
|
|
2008-03-27 14:29:33 +00:00
|
|
|
WORD Flags:
|
|
|
|
LAYER_IS_READABLE = 0x0001
|
|
|
|
LAYER_IS_WRITABLE = 0x0002
|
|
|
|
LAYER_IS_LOCKMOVE = 0x0004
|
|
|
|
LAYER_IS_BACKGROUND = 0x0008
|
2007-09-18 23:57:02 +00:00
|
|
|
WORD Layer type (0=normal (image) layer, 1=layer set)
|
|
|
|
WORD Layer child level (see NOTE.1)
|
|
|
|
WORD Default layer width in pixels (ignored)
|
|
|
|
WORD Default layer height in pixels (ignored)
|
|
|
|
WORD Blend mode (always 0 for layer set)
|
2008-03-27 14:29:33 +00:00
|
|
|
BLEND_MODE_NORMAL = 0
|
|
|
|
BLEND_MODE_DISSOLVE = 1
|
|
|
|
BLEND_MODE_MULTIPLY = 2
|
|
|
|
BLEND_MODE_SCREEN = 3
|
|
|
|
BLEND_MODE_OVERLAY = 4
|
2007-09-18 23:57:02 +00:00
|
|
|
BLEND_MODE_HARD_LIGHT = 5
|
2008-03-27 14:29:33 +00:00
|
|
|
BLEND_MODE_DODGE = 6
|
|
|
|
BLEND_MODE_BURN = 7
|
|
|
|
BLEND_MODE_DARKEN = 8
|
|
|
|
BLEND_MODE_LIGHTEN = 9
|
|
|
|
BLEND_MODE_ADDITION = 10
|
|
|
|
BLEND_MODE_SUBTRACT = 11
|
2007-09-18 23:57:02 +00:00
|
|
|
BLEND_MODE_DIFFERENCE = 12
|
2008-03-27 14:29:33 +00:00
|
|
|
BLEND_MODE_HUE = 13
|
2007-09-18 23:57:02 +00:00
|
|
|
BLEND_MODE_SATURATION = 14
|
2008-03-27 14:29:33 +00:00
|
|
|
BLEND_MODE_COLOR = 15
|
2007-09-18 23:57:02 +00:00
|
|
|
BLEND_MODE_LUMINOSITY = 16
|
2008-03-27 14:29:33 +00:00
|
|
|
BLEND_MODE_COPY = 17
|
2007-09-18 23:57:02 +00:00
|
|
|
BYTE[4] For future (set to zero)
|
|
|
|
STRING Layer name
|
|
|
|
|
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
Cel Chunk (0x2005)
|
2007-09-18 23:57:02 +00:00
|
|
|
----------------------------------------
|
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
This chunk determine where to put a cel in the specified
|
|
|
|
layer/frame.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
WORD Layer index (see NOTE.2)
|
|
|
|
WORD X position
|
|
|
|
WORD Y position
|
|
|
|
BYTE Opacity level
|
2007-11-16 20:49:40 +00:00
|
|
|
WORD Cel type
|
2007-09-18 23:57:02 +00:00
|
|
|
BYTE[7] For future (set to zero)
|
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
+ For cel type = 0 (Raw Cel):
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
WORD Width in pixels
|
|
|
|
WORD Height in pixels
|
2010-03-28 19:18:15 +00:00
|
|
|
PIXEL[] Raw pixel data: row by row from top to bottom,
|
|
|
|
for each scanline read pixels from left to right.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
+ For cel type = 1 (Linked Cel):
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
WORD Frame position to link with
|
|
|
|
|
2010-03-28 19:18:15 +00:00
|
|
|
+ For cel type = 2 (compressed image):
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
WORD Width in pixels
|
|
|
|
WORD Height in pixels
|
2010-03-28 19:18:15 +00:00
|
|
|
BYTE[] Compressed "Raw Cel" data. Details about the
|
|
|
|
compression method:
|
|
|
|
http://www.ietf.org/rfc/rfc1951.txt
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
|
2008-03-27 14:29:33 +00:00
|
|
|
Mask Chunk (0x2016) DEPRECATED
|
2007-09-18 23:57:02 +00:00
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
WORD X position
|
|
|
|
WORD Y position
|
|
|
|
WORD Width
|
|
|
|
WORD Height
|
|
|
|
BYTE[8] For future (set to zero)
|
|
|
|
STRING Mask name
|
|
|
|
BYTE[] Bit map data (size = height*((width+7)/8))
|
|
|
|
Each byte contains 8 pixels (the leftmost pixels are
|
|
|
|
packed into the high order bits)
|
|
|
|
|
|
|
|
|
|
|
|
Path Chunk (0x2017)
|
|
|
|
----------------------------------------
|
|
|
|
|
2007-12-05 01:30:50 +00:00
|
|
|
Never used.
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
Notes
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
NOTE.1: The child level is used to show the relationship of this
|
|
|
|
layer with the last one read, for example:
|
|
|
|
|
|
|
|
Layer name and hierarchy Child Level
|
|
|
|
-----------------------------------------------
|
|
|
|
- Background 0
|
|
|
|
`- Layer1 1
|
|
|
|
- Foreground 0
|
|
|
|
|- My set1 1
|
|
|
|
| `- Layer2 2
|
|
|
|
`- Layer3 1
|
|
|
|
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
NOTE.2: The layer index is a number to identify any layer in the
|
|
|
|
sprite, for example:
|
|
|
|
|
|
|
|
Layer name and hierarchy Layer index
|
|
|
|
-----------------------------------------------
|
|
|
|
- Background 0
|
|
|
|
`- Layer1 1
|
|
|
|
- Foreground 2
|
|
|
|
|- My set1 3
|
|
|
|
| `- Layer2 4
|
|
|
|
`- Layer3 5
|
|
|
|
|
2008-02-04 02:37:26 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
========================================
|
|
|
|
File Format Changes
|
|
|
|
========================================
|
|
|
|
|
|
|
|
1) The first change from the first release of the new .ase format,
|
|
|
|
is the new frame duration field. This is because now each frame
|
|
|
|
can have different duration.
|
|
|
|
|
|
|
|
How to read both formats (old and new one)? You should set all
|
|
|
|
frames durations to the "speed" field read from the main ASE
|
|
|
|
header. Then, if you found a frame with the frame-duration
|
2007-11-16 20:49:40 +00:00
|
|
|
field > 0, you should update the duration of the frame with
|
|
|
|
that value.
|
2008-03-27 14:29:33 +00:00
|
|
|
|
|
|
|
2) The format of ASE 0.6 beta has a header with a background color
|
|
|
|
after the two last reserved DWORD
|
|
|
|
|
|
|
|
...
|
|
|
|
WORD Speed (milliseconds between frame, like in FLC files)
|
|
|
|
DWORD Set be 0
|
|
|
|
DWORD Set be 0
|
|
|
|
DWORD Background-color <------ *
|
|
|
|
BYTE[96] For future (set to zero)
|
|
|
|
|
|
|
|
* This field is deprecated, and now it should be 0 or his value
|
|
|
|
should be completely ignored. The only drawback is that the
|
|
|
|
sprite will have a transparent background instead of a colored
|
|
|
|
one.
|