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
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 $? 0
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 $? 0