7. Maps

[NOTE: Maps are not supported in Version 2.1 of the translator]

Syntax Summary
map name(type) {    // map declaration
    bitstring, value,
    [bitstring, value, ...]
}

type(name) varspec; // map use

7.1 Simple Maps

Maps are used to define constant- or variable-length mappings between bitstream values and object variables.

The map keyword indicates the declaration of a map named name. The map converts bitstring values to values of type type. The type indication can be a fundamental type, a class type, or an array. The contents of the map are a series of pairs of a bitstring and the value (of type type) to which this bitstring corresponds. If the value is a complex one (array or class), it must be enclosed in curly braces ({}). The bitstrings can have the same or different lengths. No bitstring is allowed to be a prefix of another bitstring, to ensure unique decodability of the mapping.

Map declarations can only occur in global scope. As a result, an array declaration will have to have a constant size (no non-constant variables are visible at this level).

The following is a simple example of a map declaration.

    map A(int) {
        0b1, 1,
        0b01, 2
    }

After the map is properly declared, we can now define parsable variables that use it by indicating the name of the map where we would put the parse size expression. The type of the map and the variable must be identical. The general syntax is:

    type(map_name)var;

For example:

    int(A) i;

The semantics of this declaration is as follows. The bitstream is examined so that one of the map's bitstrings matches the current input. For the matched bitstring, the declared variable (here i), is assigned the value that corresponds to that bitstring in the map's declaration. For example, if the next bit in the bitstream is 1, then i will be assigned the value 2.

As we can see, the use of a map is essentially identical to the declaration of regular parsable variables; all the details are hidden away in the map declaration.

The following is an example in which the map type is a complex one.

    class YUVblocks {
        unsigned int Yblocks;
        unsigned int Ublocks;
        unsigned int Vblocks;
    }

    // number of blocks per component
    map BPC (YUVblocks) {
        0b00, {4, 1, 1},
        0b01, {4, 2, 2},
        0b10, {4, 4, 4}
    }

    YUVblocks chroma_format(BPC) a;

7.2 Extended Maps

When variable-length coding is used, codeword lengths tend to get very large when their number increases. It is then typical to specify "escape codes," signifying that the actual value will be subsequently represented using a fixed-length code. To accommodate these as well as more sophisticated constructs, Flavor allows the use of parsable type indications in map values. This means that we can write:

    map A(int) {
        0b1,    1,
        0b01,   2,
        0b001, int(5)
    }

This indicates that, when the bitstring 0b001 is encountered in the bitstream, the actual return value for the map will be obtained by parsing 5 more bits. The parse size for the extension can itself be a map, thus allowing the cascading of maps in sophisticated ways.