run DCT, quantize and write Huffman bit codes
| 250 | |
| 251 | // run DCT, quantize and write Huffman bit codes |
| 252 | int16_t encodeBlock(BitWriter& writer, float block[8][8], const float scaled[8*8], int16_t lastDC, |
| 253 | const BitCode huffmanDC[256], const BitCode huffmanAC[256], const BitCode* codewords) |
| 254 | { |
| 255 | // "linearize" the 8x8 block, treat it as a flat array of 64 floats |
| 256 | auto block64 = (float*) block; |
| 257 | |
| 258 | // DCT: rows |
| 259 | for (auto offset = 0; offset < 8; offset++) |
| 260 | DCT(block64 + offset*8, 1); |
| 261 | // DCT: columns |
| 262 | for (auto offset = 0; offset < 8; offset++) |
| 263 | DCT(block64 + offset*1, 8); |
| 264 | |
| 265 | // scale |
| 266 | for (auto i = 0; i < 8*8; i++) |
| 267 | block64[i] *= scaled[i]; |
| 268 | |
| 269 | // encode DC (the first coefficient is the "average color" of the 8x8 block) |
| 270 | auto DC = int(block64[0] + (block64[0] >= 0 ? +0.5f : -0.5f)); // C++11's nearbyint() achieves a similar effect |
| 271 | |
| 272 | // quantize and zigzag the other 63 coefficients |
| 273 | auto posNonZero = 0; // find last coefficient which is not zero (because trailing zeros are encoded differently) |
| 274 | int16_t quantized[8*8]; |
| 275 | for (auto i = 1; i < 8*8; i++) // start at 1 because block64[0]=DC was already processed |
| 276 | { |
| 277 | auto value = block64[ZigZagInv[i]]; |
| 278 | // round to nearest integer |
| 279 | quantized[i] = int(value + (value >= 0 ? +0.5f : -0.5f)); // C++11's nearbyint() achieves a similar effect |
| 280 | // remember offset of last non-zero coefficient |
| 281 | if (quantized[i] != 0) |
| 282 | posNonZero = i; |
| 283 | } |
| 284 | |
| 285 | // same "average color" as previous block ? |
| 286 | auto diff = DC - lastDC; |
| 287 | if (diff == 0) |
| 288 | writer << huffmanDC[0x00]; // yes, write a special short symbol |
| 289 | else |
| 290 | { |
| 291 | auto bits = codewords[diff]; // nope, encode the difference to previous block's average color |
| 292 | writer << huffmanDC[bits.numBits] << bits; |
| 293 | } |
| 294 | |
| 295 | // encode ACs (quantized[1..63]) |
| 296 | auto offset = 0; // upper 4 bits count the number of consecutive zeros |
| 297 | for (auto i = 1; i <= posNonZero; i++) // quantized[0] was already written, skip all trailing zeros, too |
| 298 | { |
| 299 | // zeros are encoded in a special way |
| 300 | while (quantized[i] == 0) // found another zero ? |
| 301 | { |
| 302 | offset += 0x10; // add 1 to the upper 4 bits |
| 303 | // split into blocks of at most 16 consecutive zeros |
| 304 | if (offset > 0xF0) // remember, the counter is in the upper 4 bits, 0xF = 15 |
| 305 | { |
| 306 | writer << huffmanAC[0xF0]; // 0xF0 is a special code for "16 zeros" |
| 307 | offset = 0; |
| 308 | } |
| 309 | i++; |