Lossy block averaging (source code)

= Lossy block averaging
{title2=$q_{ij}=\lfloor m_{ij}+1/2\rfloor$}

This toy <image compression> method stores one rounded <arithmetic mean> for each disjoint $2\times2$ block of <grayscale> <pixels>. The <quantization (signal processing)> rule is round to the nearest <integer>, with exact halves rounded upward. Each stored value is an unsigned eight-<bit> <integer>. Reconstruction fills the original block with that value, a form of <nearest-neighbor interpolation>. Averaging already discards information; rounding can discard more.

Here is an exact $16\times16$ source <array>. Index rows and columns by $r,c\in\{0,\ldots,15\}$ and define
$$
\begin{aligned}
b_{rc}&=40+10\lfloor r/2\rfloor+12\lfloor c/2\rfloor,\\
x_{rc}&=b_{rc}+20(-1)^{r+c}+\mathbf{1}_{\{r\text{ even},\ c\text{ even}\}}.
\end{aligned}
$$
The <floor function> makes $b$ constant within each block; the <indicator function> adds 1 only to its upper-left <pixel>. All values are <integers> from 20 to 215. Each block therefore has the exact form
$$
\begin{pmatrix}b+21&b-20\\b-20&b+20\end{pmatrix},\qquad m=b+\tfrac14,\qquad q=\lfloor m+\tfrac12\rfloor=b.
$$
For example, the upper-left block $\left(\begin{smallmatrix}61&20\\20&60\end{smallmatrix}\right)$ has <arithmetic mean> $161/4=40.25$ and is stored as 40. The block immediately to its right $\left(\begin{smallmatrix}73&32\\32&72\end{smallmatrix}\right)$ is stored as 52. The complete stored $8\times8$ <array> is specified by $q_{ij}=40+10i+12j$ for $0\leq i,j\leq7$. Its first row is $40,52,64,76,88,100,112,124$; its last is $110,122,134,146,158,170,182,194$.

This toy <file format> again has eight-<bit> width and height fields followed by a one-<bit> mode: 0 means raw eight-<bit> <grayscale> <pixels>, 1 means the rounded block <arithmetic means>. This profile accepts only width and height 16. The decoder knows the block size and reconstruction rule from the format, reads the 64 stored values in row order, and repeats each across its corresponding $2\times2$ block. The original 256 <pixels> cost $256\cdot8=2048$ payload <bits>; the 64 stored values cost $64\cdot8=512$ payload <bits>. The reduction is $75\%$. These payload counts exclude the common 17-<bit> <file header>; complete sizes are 2065 and 529 <bits>, or 2072 and 536 <bits> after final zero padding to eight-<bit> units. There is no stored codebook or additional prediction rule.

The empirical <mean squared error> averages squared differences over the 256 original <pixel> positions:
$$
\operatorname{MSE}=\frac1{256}\sum_{r=0}^{15}\sum_{c=0}^{15}(x_{rc}-\widehat x_{rc})^2
=\frac{21^2+20^2+20^2+20^2}{4}=410.25.
$$
Every block has the same four errors, so this value is exact in squared stored shade units. If the unrounded <arithmetic mean> $b+1/4$ could be reconstructed, the error would instead be $410.1875$; eight-<bit> <quantization (signal processing)> adds $0.0625$. That hypothetical comparison does not count fractional means as free eight-<bit> values.

The broad shade pattern survives, while the alternating bright and dark <pixels> vanish. Indeed, a second source with every block constant at $b$ produces the identical stored <array> $q$: exact decoding of both sources is impossible. This makes the storage benefit and the lost detail visible at once. Block averaging is useful for a coarse preview when the individual <pixels> are dispensable; choosing an acceptable <mean squared error> or visual result is part of the application, not a guarantee supplied by the encoder.

\Image[/lossy-block-image-comparison.png]
{title=Rounded 2 by 2 block means reduce the payload by 75 percent while destroying fine detail}