So it turned out that the refinement pass was actually pretty easy to do.
Lets say I’m compressing a pixel with a value of -129 and I’m using a threshold of 128. I push into a vector the value |129| – 128. ie the absoloute value minus the threshold. I subsequently do this for every pixel above my threshold.
pixelsForRefinement.push_back( absVal - threshold );
I then halve the threshold and do the same sort of processing again. Now I run through the values that were pushed into my vector on the pass before hand and I do a simple check. Is the value in the vector (in the example case 1) greater than 128? No so I write a 0 to the refinement stream. If it IS greater than I write a 1 to the refinement stream and subtract the threshold value from the value stored in the vector.
// We now need to refine the pixels that were added on the previous pass
uint32_t refinement = 0;
uint32_t refinementMax = lastNumPixelsForRefinement;
while( refinement < refinementMax )
{
const int16_t val = pixelsForRefinement[refinement];
const BitEncoding::Bit bit = (val >= threshold) ? BitEncoding::Bit_One : BitEncoding::Bit_Zero;
pixelsForRefinement[refinement] -= (threshold * (uint32_t)bit);
bitStreamOut.refineBitStream += bit;
refinement++;
}
lastNumPixelsForRefinement = pixelsForRefinement.size();
Effectively this means that for each pass through I refine the already WDR’d pixels by the current threshold.
The result is a perfect re-construction from the wavelet information (I shan’t bother posting up a before and after picture as they look the same ;)).
Now to get some form of compression I need to be able to early out from the algorithm and, basically, only store high frequency information (as well as the low frequency image in the first place). This posed a slight problem, however as I need to be able to perform the compression on each wavelet step as I go along. The system I had built thus far performed the compression on all the LH etc segments for each wavelet decomposition level. I needed to do some code re-organisation to get it do them in the correct order (ie LH, HL and HH). It wasn’t too difficult.
At this point though I realised I could MASSIVELY simplify the wavelet transforms. This I will explain in the next article.