MCPcopy Create free account
hub / github.com/InteractiveComputerGraphics/SPlisHSPlasH / encodeBlock

Function encodeBlock

extern/toojpeg/toojpeg.cpp:252–323  ·  view source on GitHub ↗

run DCT, quantize and write Huffman bit codes

Source from the content-addressed store, hash-verified

250
251// run DCT, quantize and write Huffman bit codes
252int16_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++;

Callers 1

writeJpegFunction · 0.85

Calls 1

DCTFunction · 0.85

Tested by

no test coverage detected