# What does the author mean in these reverse engineering notes?

I am trying to write a decoder for an old video format used in a DOS game, the Psygnosis SMV video format, but I'm having a hard time understanding the image decoding process, specifically this section:

``````Macroblocks drawing

Macroblocks are stored in the following format:

u8 pixels[16 * num_mblocks]
u4 nibbles[num_mblocks]

Size of pixels[] is equal to ST chunk's nibbles.
For each macroblock draw it by indexing its pixels by nibbles.
First nibble stored in top 4 bits of byte.
``````

Here are the properties of the frame I am trying to decode:

• image width = 320
• image height = 192
• macroblock width = 16
• macroblock height = 16
• nibbles = 3840
• frame size in bytes = 34560

So according these, I computed the following values:

``````num_mblocks = nibbles / 16 = 3840 / 16 = 240 macroblocks

further checking:
(image width / macroblock width) * (image height / macroblock height)
= (320 / 16) * (192 / 16)
= 20 * 12
= 240 macroblocks
``````

1st problem:

The size of `u8 pixels[16 * num_mblocks]` is indeed 3840 bytes, but what is the size of `u4 nibbles[num_mblocks]` supposed to be ? 240 bytes or half that amount since the type is `u4` ?

2nd problem:

When I divide the `frame size in bytes` by the number of `macroblocks` I end up with only 144 bytes per macroblock (34560 / 240 = 144), but to me this is very far from what it's supposed to be, I guess I'm wrong somewhere.

3rd problem:

The author wrote:

For each macroblock draw it by indexing its pixels by nibbles.

But what does that mean exactly ?

Question

Can you explain/shed some light on how one is supposed to decode a frame ?

NB: This is an assumption which may or may not be true; I haven't tested that against any real file.

It seems like the creators of the file format have been trying to save some space. They want to encode 256 colors ("to encode 8-bit palettized video"), so they'd need one byte per pixel. However, a certain smaller area of the screen ise likely to contain the same color pixels repeatedly. So, I'd say that each macroblock can contain only 16 different colors, representable in 4 bits/one nibble.

From `u8 pixels[16 * num_mblocks]` it seems like each macroblock has 16 pixel definitions, which are indexes into the general palette table, and need 1 byte each. What follows is one nibble per pixel which is an index into `pixels`.

So, for example, the pixels for one macro block would have 16 bytes which are indexes into the palette; which may look like this: (Sorry for some of the color names; i ran out of names that fit in 5 characters ...)

``````+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
+  1  +  2  +  3  +  4  +  5  +  6  +  7  +  8  +  9  +  A  +  B  +  C  +  D  +  E  +  F  +
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
| red |green|blue |yellw|magnt|cyan |grey |black|orang|gold |aqua |azure|ivory|plum |wheat|
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
``````

Next, you need one nibble per pixel which is an index into that table. So the bytes CA 53 2D would represent 6 pixels being azure, gold, magenta, blue, green, and ivory.

So for a macroblock of 256 pixels you need 16 bytes for the pixel table, and 256/2=128 bytes for the pixels. Which sums up to the 144 that you calculated. The `u4 nibbles[num_mblocks]` is probably wrong and should be `u4 nibbles[num_mblocks*pixels_per_mblock]`

• Thank you, I've been digging using your answer, however, I have an incorrect picture ... I started to suspect my implementation of that LZ77-like decompression and decided to attack the simplest thing in the format : decompress packed music chunks; while the algo produces the exact number of bytes, the content is wrong ... I'm actually struggling with this part !
– aybe
Nov 16 '16 at 21:10