Основы сжатия JPEG
Я читал сжатие Jpeg, но у меня возникли проблемы с пониманием основ! пожалуйста, посмотрите эту схему
http://www.cs.cf.ac.uk/Dave/Multimedia/Topic5.fig_29.gif
Моя проблема в последних шагах, рассмотрим, у нас есть серое изображение 16*16 пикселей, поэтому у нас есть 4 блока размером 8*8. в зигзагообразном сканировании у нас есть 4 массива размером 1*64, первый индекс каждого массива которых является значением постоянного тока, а остальные 63 значения являются компонентами переменного тока. давайте предположим, что как;
BLOCK-1::150,-1, 6, 0,-3,....
BLOCK-2:-38, 4,-6,-1, 1,....
BLOCK-3:18,-2,3,4,1,....
BLOCK-4:45,3,5,-1,1,....
Я знаю, что DPCM кодирует разницу с предыдущими блоками 8 * 8, но как?! что-то вроде этого:
150,150-(-38),-38-18,45-18>>
150,188,-156,27
тогда согласно таблице кодирования коэффициента JPEG мы имеем
10010110-111110,10111100-111110,01100011-111110,11011-110
и для компонента AC (например) первой строки (-1, 6, 0,-3,....) мы используем RLE, поэтому имеем:
(0,-1),(0,6),(1,-3),...
тогда в соответствии с таблицей кодов переменного тока JPEG по умолчанию имеем:
00-0,100-110,111001-10
и если мои расчеты верны, что будет дальше?! ставим первый DC первого блока и после этого RLE из 63 оставшихся значений и так далее? Я имею в виду для первого блока у нас есть 10010110-111110 ,00-0,100-110,111001-10, ...
Я немного растерялся и нигде не смог найти ответ:(
1 ответ
Прежде всего, я настоятельно рекомендую вам обратиться к jpec крошечному кодеру JPEG, написанному на C (только в градациях серого, базовый JPEG на основе DCT, только блоки 8x8).
Вы можете найти основные шаги сжатия здесь. В частности, обратитесь к этой строке, которая соответствует этапу энтропийного кодирования текущего блока.
DPCM кодирует разницу с предыдущими 8*8 блоками, но как?
Энтропийное кодирование работает блок за блоком. Предполагая, что текущий блок не является пустым, кодирование коэффициента постоянного тока выполняется, сначала вычисляя разницу между текущим и предыдущим значениями постоянного тока:
int val, bits, nbits;
/* DC coefficient encoding */
if (block->len > 0) {
val = block->zz[0] - s->dc;
s->dc = block->zz[0];
}
Замечания: s
представляют состояние энтропийного кодера. Кроме того, для первого блока, s->dc
инициализируется до 0.
Так val
представляет текущую разницу DC:
- размер этой разности (= количество бит) кодируется путем считывания соответствующего кода DC в таблице Хаффмана,
- затем его амплитуда (= значение) кодируется.
Если разница отрицательная, используется дополнение до двух.
bits = val;
if (val < 0) {
val = -val;
bits = ~val;
}
JPEC_HUFF_NBITS(nbits, val);
jpec_huff_write_bits(s, jpec_dc_code[nbits], jpec_dc_len[nbits]); /* (1) */
if (nbits) jpec_huff_write_bits(s, (unsigned int) bits, nbits); /* (2) */
Для полной версии, пожалуйста, обратитесь к этому разделу кода.