# Matrix Color Conversion

Each color channel is going through 4 stages that each look like this: (I+A)*E+O

```I = input (25bit unsigned)
E = matrix coefficient (18bit signed)
O = offset (48bit signed)
```

The four stages are connected together that the offset of stage N is the output of stage N-1. The offset of stage 1 is set in registers (32-35). The output of stage 4 is the final result.

For each channel that results in the following fomular:

```Ri = SUMj ((Ij + Aij) * Eij) + Oi
```

Which in other words mean the result of matrix (Eij) multiplied with an input vector (Ij + Aij) plus an offset vector (Oi).

Currently all registers (beside input/output) are shortened to 16bit signed (this could be changed easily) values so the matrix is currently limited to 1/256 of the possible accuracy (due to a 8bit shift of the output).

All input /output register are tested for over/underflow and clipped to 12 bit (this can also be disabled).

Setting/Getting Registers:

```. ./hdmi.func # load functions
```
```mat_reg 0 # Read value of register 0 = A0
mat_reg 0 1 # Sett value of register 0 (A0) to 1
```

4x4 matrix coefficients (A0, A1, A2, A3, B0, B1, B2, B3, B4, C0, C1, C2, C3, D0, D1, D2, D3) are mapped to addresses 0 - 15. In registers 16 - 31 there are adjustment values and from 32 - 35 there are 4 offset values.

Input format per default is (R, G1, G2, B).

All values of the 4x4 matrix can be set conveniently with this script:

Syntax:

```./mat4_conf.sh  A0 A1 A2 A3  B0 B1 B2 B3 B4  C0 C1 C2 C3  D0 D1 D2 D3    O1 O2 O3 O4
```

Where the last quadruple is optional, it defaults to 0.

An RGB 3x3 matrix can easily be extended to a 4x4 matrix by using the coefficient for green and offsets twice or better to half both of the green coefficients and use the same value for both greens twice.