Libraries to parse and (maybe) encode .reia file for sims2
Belladonna.Cove.mp4
.reia
files are how Sims2 stores the videos for its neighborhood previews in
its main menu. They seem to be a relatively custom format, this is an overview
on how it encodes video data:
.reia
files first have a header with metadata, the fields are:
Offsets | Type | Description (values in hex) |
---|---|---|
0x00 - 0x03 |
Magic | 52 49 46 46 "RIFF" |
0x04 - 0x07 |
uint32 | Size of the "chunk" which is the rest of the file |
0x08 - 0x0f |
Magic | 52 65 69 61 68 65 61 64 "Reiahead" |
0x10 - 0x13 |
uint32 | 18 Size of the metadata to follow (always 24 in practice) |
0x14 - 0x17 |
uint32 | 01 Unknown, always 1 |
0x18 - 0x1b |
uint32 | Horizontal resolution in pixels |
0x1c - 0x1f |
uint32 | Vertical resolution in pixels |
0x20 - 0x23 |
uint32 | Frames per second numerator (see below) |
0x24 - 0x27 |
uint32 | FPS denominator. FPS given by fps_numerator/fps_denominator |
0x28 - 0x2b |
uint32 | Number of frames in the file |
... |
frames | See below |
After the header, there are a sequence of frames. Each frame is
Offsets | Type | Description (values in hex) |
---|---|---|
0x00 - 0x03 |
Magic | 66 72 6d 65 "frme" |
0x04 - 0x07 |
uint32 | Size of the frame data to follow |
... |
Frame Data | See below |
Note that the frame data is padded to be 2-byte aligned. So if the frame size
was 3
, there will be 4
bytes of data instead of 3 before the next
frme
magic bytes.
The format uses some interesting tricks for compression: run-length encoding, encoding differences in pixel values between frames and reusing blocks of pixels that stay the same.
Each pixel has a standard 24-bit color depth storing 8-bits for the RGB channels in little endian.
Images are stored in blocks of 32x32
pixels. So a reia file with a resolution
of 128x128
is constructed of 4x4 = 16
blocks. Each block is parsed as
follows:
-
A single byte is read.
0
indicates this32x32
block should be reused from the previous frame. Any other value means the block data is to follow. -
A byte is read and treated as a signed 8-bit integer
n
:- If the value is negative, then a single pixel value should be read and
repeated
(-n) + 1
times. - If the value is positive, then
n + 1
unique pixel values should be read.
- If the value is negative, then a single pixel value should be read and
repeated
-
The pixel values retrieved are relative to the previous frame unless it is the first frame of the file. So a change from a red value of
200
to205
is encoded as5
. A change from255
to0
is encoded as1
.In order to get the actual pixel value you must use
(previous + current) & 0xFF
.