JPEG image compression is Fourier based DCT (ITU 81). It divides the image into 8x8 pixel blocks, and processes each using a Discrete Cosine Transform. The results are quantised and then encoded.

Looking at the MSDN documentation:

It seems that both width and height are required to be a multiple of 16 to perform a perfect 90° rotation.

Now if we inspect the source code of the open-source implementation jpegtran, we realize that the width / height are required to be a multiple of 8 to perform a perfect 90° rotation:

jtransform_perfect_transform(JDIMENSION image_width, JDIMENSION image_height,
  case JXFORM_ROT_90:
    if (image_height % (JDIMENSION)MCU_height)
      result = FALSE;


Which can easily verified from the command line:

% convert -size 808x808 xc:white canvas.jpg
% jpegtran -perfect -rotate 90 -outfile rot90.jpg canvas.jpg && echo $?

So in conclusion it appears that perfect rotation can be achieved with image size being multiple of 8, since we are only shuffling values within one 8x8 block.

Why would MSDN documentation take extra care and require image size be multiple of 16, then ? Or is jpegtran actually producing non-perfect 90° rotation ?

Update. My original test was using single scalar (1 component), if I try with 3 components I get the same result:

% convert -size 808x808 xc:#990000 canvas2.jpg
% file canvas2.jpg
canvas2.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 808x808, components 3
% jpegtran -perfect -rotate 90 -outfile rot90.jpg canvas2.jpg && echo $?
  • 2
    $\begingroup$ There are many different ways to encode JPG images. Are you sure multiples of 8 can be used in all cases, like when colors are subsampled by a factor of two? $\endgroup$
    – Justme
    Jun 15 at 14:32

The basic unit for color components is 8 by 8 only if no chroma subsampling is used, i.e 4:4:4 format. Most likely your test image uses this, but not all images do.

When 4:2:2 chroma subsampling is used, the basic unit is 16 by 8 pixels.

In 4:2:0 chroma subsampling, the basic unit is 16 by 16 pixels.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.