> Why are you normalizing to 1 and after that ruining normalization with multiplication?
As opposed to doing what? It's hard for me to explain what I'm doing wrong if no one explains how to do things right. The colour space matrix multiplication is kind of an afterthought to the way I'm doing this, what I do makes more sense if you exclude it. Every stage of my processing is meant to be visible with a rather consistent approach to gain, so naturally it starts with subtracting black levels and normalisation. I divide the WB coefs from cam_mul by their minimum (green, because I don't understand why the green coef should ever be less than 1.0), so that green stays normalised while red and blue can go higher than 1.0 but are clipped on screen (but not in the data) so that at that stage highlights are white on screen but purple in the data.

Is it after the white balance multiplication that I should clip the data to 1.0? I don't like that it means I'm throwing data away, but I guess that makes sense if I'm not going to do highlight recovery and that the matrix multiplication will make the higher red and blue values push green down. So I guess I should clip, do the colour space conversion, then make things normalised again by dividing everything by the lowest value from the result of (1 , 1 , 1) × the matrix (and then clip again?).

> Why are you normalizing to 1 and after that ruining normalization with multiplication?

As opposed to doing what? It's hard for me to explain what I'm doing wrong if no one explains how to do things right. The colour space matrix multiplication is kind of an afterthought to the way I'm doing this, what I do makes more sense if you exclude it. Every stage of my processing is meant to be visible with a rather consistent approach to gain, so naturally it starts with subtracting black levels and normalisation. I divide the WB coefs from cam_mul by their minimum (green, because I don't understand why the green coef should ever be less than 1.0), so that green stays normalised while red and blue can go higher than 1.0 but are clipped on screen (but not in the data) so that at that stage highlights are white on screen but purple in the data.

Is it after the white balance multiplication that I should clip the data to 1.0? I don't like that it means I'm throwing data away, but I guess that makes sense if I'm not going to do highlight recovery and that the matrix multiplication will make the higher red and blue values push green down. So I guess I should clip, do the colour space conversion, then make things normalised again by dividing everything by the lowest value from the result of (1 , 1 , 1) × the matrix (and then clip again?).