Skip to main content
gamedev.net
🔒 Locked

jpeg compression

Started by rumble 4 replies 1.3k views
Original Post
rumble
rumble
I read jpegs are split into typically 8x8 pixel tiles which are transformed to frequency space representations. Sometimes 8x16 and 16x16 tiles are used.

Is there any reason the standard doesn't use 4x4 tiles? Or 6x6? Or 5x5?

If the standard allows only 4x4 tiles for compression, would the result be having better details but larger in size?

Would be interested if there are some examples.

Thanks
Sneftel
Sneftel
It's more a size/size tradeoff than a size/quality tradeoff. Smaller blocks lead to the need to store more blocks, but require a lower number of DCT coefficients and therefore don't have to quantize them as much. 4x4 is probably too small for the DCT to be useful. My guess would be that power-of-2 blocks are easier to transform for some reason, but that's just off-the-cuff.
Antheus
Antheus
Is there any reason the standard doesn't use 4x4 tiles? Or 6x6? Or 5x5?[/quote]They decided so. It's arbitrary.

Quality of results as much of similar data in video codecs was determined through psychometric testing in blind studies. They simply went with things that looked best to most people.

If the standard allows only 4x4 tiles for compression, would the result be having better details but larger in size? [/quote]
An overview of the process (pdf).

Since transform itself is lossless and data loss occurs after most values are discarded, the compression depends on ratio of zero vs. non-zero elements. To preserve same amount of detail, having smaller macroblock would likely lead to worse compression. Quantization must reduce as many elements as possible to zero and smaller blocks would cause show more quantization errors.

JPEG2000 uses SDCT, which has variable block size. But higher hardware requirements mean it's less used.
Krypt0n
Krypt0n

I read jpegs are split into typically 8x8 pixel tiles which are transformed to frequency space representations. Sometimes 8x16 and 16x16 tiles are used.

I think jpeg always uses 8x8, mpeg has 16x16 and newer versions divide those blocks into smaller blocks.


the smaller the block is, the less frequencies are covered in every entry of your DCTransformed matrix. splitting them into finer frequencies aka bigger blocks, results into finer grain selection of what frequencies you can reject/reduce.

On the other side, the bigger the blocks are, the more noticeable are the discontinuities on the borders between blocks and even small quantizations that happen due to float->int conversion (as you do your math with floats, but save 8bit ints) propagate across the hole block. you don't notice that with just one block, but with several blocks next to each other you see it.

Your next question might be "why not transform the whole picture as one block", the reason is the inaccuracy you get with using float, you get some really big numbers from accumulating thousands or millions of tiny float numbers, that will lead to a lot of data loss, as addition and subtraction on floats isn't such a great idea if you need consistency, e.g. 10000.0f+0.0001f -> 10000.f

yes, you could solve this with a math lib that works on big fixed point numbers to some degree. you'd still need to deal with quantization just due to truncation once you want to save those values to file.


Is there any reason the standard doesn't use 4x4 tiles? Or 6x6? Or 5x5?

[/quote]


the reason is that power of two Fourier transforms can be optimized better, it's called "Fast Frourier Transform" or FFT, and even then it took sometimes a minute to compress a picture, nearly 20 years ago, when jpgs and gifs were the mainly used formats


If the standard allows only 4x4 tiles for compression, would the result be having better details but larger in size?

[/quote]


the size vs quality in jpg is a matter of setting, so you could probably always reach similar sizes.

In terms of quality, it's somehow dependent on the way you measure and the test data.

using some purely mathematic validation like mean-square-error, you will not take discontinuities into account. using some human vote might be very individual. some people are fine with their old noisy digicams that compress 100 pictures to 1kb, some people say they get head ache when watching online rented movies, as the quality is so bad compared to BR or even DVD.

the choice in using 16x16 for movies was mainly driven by higher compression needs.


On one side you need in general a better ration, to accomplish 24frame/s for 1hour (btw. it also decompresses a little bit faster on the binary level), they also reduced the YCbCr ration from 4:1:1 to 16:1:1 for that reason. The other reason is that you need to store motion vectors per block, 16x16 as 1/4th of motion vectors to transfer. (and those are kinda the main data consumer between the key frames).







Antheus
Antheus


Your next question might be "why not transform the whole picture as one block", the reason is the inaccuracy you get with using float, you get some really big numbers from accumulating thousands or millions of tiny float numbers, that will lead to a lot of data loss, as addition and subtraction on floats isn't such a great idea if you need consistency, e.g. 10000.0f+0.0001f -> 10000.f

Accuracy is not a problem. Even in original spec, one may use lossless transformation.

The reason for small matrices has to do with type of error introduced by discarding elements. Most commonly, it would result sort of bloom effect, where image would get brighter or darker towards the edges. The whole-image wave patterns would also be visible. In signal processing, different kinds of filters are applied to compensate for related effects.

Second reason has to do with FFT being unable to represent many commonly found patterns, especially sharp edges. Since they result in essentially infinite series, removing several in frequency space causes banding after reconstruction. By using smaller blocks such errors are less visible and localized. Banding is one of most common artefacts caused by M/JPEG. If full image were handled at once, these bands would ripple over entire image.

JPEG2000 uses prograssive full-image compression, but uses wavelets (among other methods) instead of DCT which does not exhibit same type of problems.
Krypt0n
Krypt0n

[quote name='Krypt0n' timestamp='1300965642' post='4789901']
Your next question might be "why not transform the whole picture as one block", the reason is the inaccuracy you get with using float, you get some really big numbers from accumulating thousands or millions of tiny float numbers, that will lead to a lot of data loss, as addition and subtraction on floats isn't such a great idea if you need consistency, e.g. 10000.0f+0.0001f -> 10000.f

Accuracy is not a problem. Even in original spec, one may use lossless transformation.
[/quote]didn't I say this and explained why it wasn't doable?

yes, you could solve this with a math lib that works on big fixed point numbers to some degree. you'd still need to deal with quantization just due to truncation once you want to save those values to file.[/quote]







The reason for small matrices has to do with type of error introduced by discarding elements. Most commonly, it would result sort of bloom effect, where image would get brighter or darker towards the edges. The whole-image wave patterns would also be visible. In signal processing, different kinds of filters are applied to compensate for related effects.



Second reason has to do with FFT being unable to represent many commonly found patterns, especially sharp edges. Since they result in essentially infinite series, removing several in frequency space causes banding after reconstruction. By using smaller blocks such errors are less visible and localized. Banding is one of most common artefacts caused by M/JPEG. If full image were handled at once, these bands would ripple over entire image.[/quote]indeed, here are my experiments that show ripples and block discontinuities if using 64x64.

http://img149.images...580/lenauj8.png
using 128x128 already shows differences whether you use float or doubles (sorry, I don't have a pic of that uploaded), using dct for the whole screen


Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.