The encoder cuts each plane into 8-by-8 blocks and recenters them on zero for the forward DCT. Today you extract one block from a plane and subtract 128 from every sample.
Extract an 8-by-8 block from a sample plane at a block position and level-shift it by subtracting 128 from each sample.
The forward pipeline is per-block, so the encoder must first cut each component plane into 8-by-8 blocks. Extracting the block at block-column bx, block-row by is the mirror of the decoder’s placeBlock: read plane pixel (bx*8+col, by*8+row) into block[row*8+col]. This is the same offset indexing, run in the gathering direction instead of the scattering one.
While gathering, the encoder also level-shifts each sample by subtracting 128, moving the 0..255 pixel range down to the signed -128..127 the forward DCT expects - the exact inverse of the +128 the decoder adds at the end. So a bright 200 becomes 72, a mid-gray 128 becomes 0, and a black 0 becomes -128. Doing extraction and recentering in one pass leaves you with a signed block ready to transform, which is the next lesson.
// read plane pixel (bx*8+col, by*8+row) into block[row*8+col],// subtracting 128 to recenter the 0..255 range onto -128..127.// block[row*8+col] = int(plane[(by*8+row)*planeW + bx*8+col]) - 128func extractBlock(plane []byte, planeW, bx, by int) (block [64]int) { }