# Chroma Subsampling and JPEG Sampling Factors

- Published
- Last updated
- Revisions

There's a great deal of confusion around chroma subsampling notation between different sources and software. Chroma subsampling is generally expressed using J:a:b notation but JPEG uses a different format internally. This internal format is not well documented and thus causes even more confusion when exposed in user interfaces. This article attempts to shed some light on the different notations and how they are related.

## Common notation

Let's start with the common J:a:b notation:

*J*specifies a block of*J*× 2 pixels for luma. Typically,*J*is 4.*a*is the number of chroma samples in the first row.*b*is the number of chroma samples in the second row. This is either 0 or equal to*a*.

Chroma subsampling can also be expressed as fractions of the luma resolution. For example 4:2:2 means that the chroma resolution is halved horizontally while vertically it has full resolution. Let's denote the relative horizontal and vertical chroma resolutions with H and V. Here's a table of common chroma subsamplings in both of notations alongside a visual representation:

J:a:b | H | V | Luma | Chroma |
---|---|---|---|---|

4:4:4 | 1⁄1 | 1⁄1 | ||

4:4:0 | 1⁄1 | 1⁄2 | ||

4:2:2 | 1⁄2 | 1⁄1 | ||

4:2:0 | 1⁄2 | 1⁄2 | ||

4:1:1 | 1⁄4 | 1⁄1 | ||

4:1:0 | 1⁄4 | 1⁄2 |

## Understanding sampling factors

The typical JPEG has three channels: Y', C_{B} and C_{R} where Y' stores the luma of the image while C_{B} and C_{R} store the chroma.
To enable subsampling each channel has a horizontal and a vertical sampling factor.
Possible values for the sampling factors are integers 1, 2, 3 and 4.

The sampling factors of each channel express the channel's resolution in relation to the largest sampling factors. For example, in sampling factors 2×3, 1×2, 2×1, the largest horizontal and the vertical sampling factor which are 2 and 3 respectively. Here's an interactive animation on how an image with these sampling factors is decoded:

More formally, let's denote the sampling factors as \(h_1\)×\(v_1\), \(h_2\)×\(v_2\), \(h_3\)×\(v_3\). Then the largest horizontal and vertical sampling factors are:

\[ \begin{aligned} h_{max} &= \text{max}\{h_1, h_2, h_3\} \\ v_{max} &= \text{max}\{v_1, v_2, v_3\} \end{aligned} \]

And the relative resolutions are the following:

- the first channel has \(h_1/h_{max}\) horizontal and \(v_1/v_{max}\) vertical resolution
- the second channel has \(h_2/h_{max}\) horizontal and \(v_2/v_{max}\) vertical resolution
- the third channel has \(h_3/h_{max}\) horizontal and \(v_3/v_{max}\) vertical resolution

Let's take a look at sampling factors 2×3, 1×2, 2×1 again. First we calculate the largest sampling factors \(h_{max} = 2\) and \(v_{max} = 3\). Then the relative resolutions are the following:

- the first channel has 2⁄2 horizontal and 3⁄3 vertical resolution
- the second channel has 1⁄2 horizontal and 2⁄3 vertical resolution
- the third channel has 2⁄2 horizontal and 1⁄3 vertical resolution

Additionally, the following inequality must hold:

\[h_1 v_1 + h_2 v_2 + h_3 v_3 \leq 10\]

This means that sampling factors such as 4×3, 2×1, 2×3 are invalid because \(4 \cdot 3 + 2 \cdot 1 + 2 \cdot 3 = 20\) is greater than \(10\).

## Chroma subsampling with sampling factors

Next, let's investigate how we can express chroma subsampling with sampling factors. For chroma subsampling the luma channel must have the largest sampling factors and the sampling factors of both chroma channels must be equal. Here's a table of common chroma subsamplings with corresponding sampling factors:

J:a:b | H | V | Sampling factors |
---|---|---|---|

4:4:4 | 1⁄1 | 1⁄1 | 1×1, 1×1, 1×1 |

4:4:0 | 1⁄1 | 1⁄2 | 1×2, 1×1, 1×1 |

4:2:2 | 1⁄2 | 1⁄1 | 2×1, 1×1, 1×1 |

4:2:0 | 1⁄2 | 1⁄2 | 2×2, 1×1, 1×1 |

4:1:1 | 1⁄4 | 1⁄1 | 4×1, 1×1, 1×1 |

4:1:0 | 1⁄4 | 1⁄2 | 4×2, 1×1, 1×1 |

In the table, sampling factors of the second and third channel are all equal to 1. In this special case, the sampling factors of the first channel can be interpreted as the dimensions of a chroma sample in pixels and the rest of the sampling factors are usually omitted. For example, 1×2 is shorthand for sampling factors 1×2, 1×1, 1×1 or, put in another way, the chroma sample is 1 pixel wide and 2 pixels tall.

Because the sampling factors express ratios, they can represent the same chroma subsampling in multiple ways. Table 3 shows alternative ways of storing chroma subsampling. These should be avoided because they may not work properly in all software (see this libjpeg-turbo issue for reference).

J:a:b | H | V | Sampling factors |
---|---|---|---|

4:4:4 | 3⁄3 | 1⁄1 | 3×1, 3×1, 3×1 |

4:4:4 | 2⁄2 | 1⁄1 | 2×1, 2×1, 2×1 |

4:4:4 | 1⁄1 | 3⁄3 | 1×3, 1×3, 1×3 |

4:4:4 | 1⁄1 | 2⁄2 | 1×2, 1×2, 1×2 |

4:4:0 | 2⁄2 | 1⁄2 | 2×2, 2×1, 2×1 |

4:4:0 | 1⁄1 | 2⁄4 | 1×4, 1×2, 1×2 |

4:2:2 | 2⁄4 | 1⁄1 | 4×1, 2×1, 2×1 |

4:2:2 | 1⁄2 | 2⁄2 | 2×2, 1×2, 1×2 |

Finally, table 4 lists the rest of chroma subsamplings that can be expressed with sampling factors. These are either rarely used subsamplings, vertical versions of common options or weird fractional subsamplings.

J:a:b | H | V | Sampling factors |
---|---|---|---|

3:1:1 | 1⁄3 | 2⁄2 | 3×2, 1×2, 1×2 |

3:1:1 | 1⁄3 | 1⁄1 | 3×1, 1×1, 1×1 |

3:1:0 | 1⁄3 | 1⁄2 | 3×2, 1×1, 1×1 |

n/a | 3⁄4 | 1⁄1 | 4×1, 3×1, 3×1 |

n/a | 2⁄3 | 1⁄2 | 3×2, 2×1, 2×1 |

n/a | 2⁄3 | 1⁄1 | 3×1, 2×1, 2×1 |

n/a | 2⁄2 | 1⁄3 | 2×3, 2×1, 2×1 |

n/a | 1⁄2 | 2⁄3 | 2×3, 1×2, 1×2 |

n/a | 1⁄2 | 1⁄4 | 2×4, 1×1, 1×1 |

n/a | 1⁄2 | 1⁄3 | 2×3, 1×1, 1×1 |

n/a | 1⁄1 | 3⁄4 | 1×4, 1×3, 1×3 |

n/a | 1⁄1 | 2⁄3 | 1×3, 1×2, 1×2 |

n/a | 1⁄1 | 1⁄4 | 1×4, 1×1, 1×1 |

n/a | 1⁄1 | 1⁄3 | 1×3, 1×1, 1×1 |

In conclusion, sampling factors are very flexible as they can express anything from typical chroma subsampling to different subsampling of C_{B} and C_{R} channels and luma subsampling.
They allow multiple ways of representing the same subsampling but you should probably use the values from table 2.

## Using sampling factors

How do we go about using the sampling factors in practise?
In `cjpeg`

we can specify 4:2:2 chroma subsampling with `-sample`

option:

```
cjpeg -sample 2x1,1x1,1x1 -outfile output.jpg input.ppm
```

or use the following shorthand:

```
cjpeg -sample 2x1 -outfile output.jpg input.ppm
```

ImageMagick has a similar option called `-sampling-factor`

:

```
magick input.ppm -sampling-factor 2x1 output.jpg
```

In libjpeg we can specify chroma subsampling with `h_samp_factor`

and `v_samp_factor`

:

```
struct jpeg_compress_struct cinfo;
jpeg_create_compress(&cinfo);
cinfo.image_width = 300;
cinfo.image_height = 200;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
cinfo.comp_info[0].h_samp_factor = 2;
cinfo.comp_info[0].v_samp_factor = 1;
cinfo.comp_info[1].h_samp_factor = 1;
cinfo.comp_info[1].v_samp_factor = 1;
cinfo.comp_info[2].h_samp_factor = 1;
cinfo.comp_info[2].v_samp_factor = 1;
```

## Further reading

Wikipedia article Chroma subsampling provides a great overview on the topic and documents usage of chroma subsampling mostly in different video formats. Douglas Kerr's article Chrominance Subsampling in Digital Images (PDF) details many things covered in this article. Colin Bendell's article Why aren’t your Images using Chroma-Subsampling? studies JPEG sampling factor usage in the wild. Finally, JPEG standard (PDF) has the definite information on JPEG subsampling on pages 24 and 36-37.