Алгоритм сжатия данных rle используется в форматах. Простейшие алгоритмы сжатия: RLE и LZ77. RLE - компактность единообразия
Пусть A - матрица размеров m\times n , а k - натуральное число, не превосходящее m и n : k\leqslant\min\{m;n\} . Минором k-го порядка матрицы A называется определитель матрицы k-го порядка, образованной элементами, стоящими на пересечении произвольно выбранных k строк и k столбцов матрицы A . Обозначая миноры, номера выбранных строк будем указывать верхними индексами, а выбранных столбцов - нижними, располагая их по возрастанию.
Пример 3.4. Записать миноры разных порядков матрицы
A=\begin{pmatrix}1&2&1&0\\ 0&2&2&3\\ 1&4&3&3\end{pmatrix}\!.
Решение. Матрица A имеет размеры 3\times4 . Она имеет: 12 миноров 1-го порядка, например, минор M_{{}_2}^{{}_3}=\det(a_{32})=4 ; 18 миноров 2-го порядка, например, M_{{}_{23}}^{{}^{12}}=\begin{vmatrix}2&1\\2&2\end{vmatrix}=2 ; 4 минора 3-го порядка, например,
M_{{}_{134}}^{{}^{123}}= \begin{vmatrix}1&1&0\\0&2&3\\ 1&3&3 \end{vmatrix}=0.
В матрице A размеров m\times n минор r-го порядка называется базисным , если он отличен от нуля, а все миноры (r+1)-ro порядка равны нулю или их вообще не существует.
Рангом матрицы называется порядок базисного минора. В нулевой матрице базисного минора нет. Поэтому ранг нулевой матрицы, по определению полагают равным нулю. Ранг матрицы A обозначается \operatorname{rg}A .
Пример 3.5. Найти все базисные миноры и ранг матрицы
A=\begin{pmatrix}1&2&2&0\\0&2&2&3\\0&0&0&0\end{pmatrix}\!.
Решение. Все миноры третьего порядка данной матрицы равны нулю, так как у этих определителей третья строка нулевая. Поэтому базисным может быть только минор второго порядка, расположенный в первых двух строках матрицы. Перебирая 6 возможных миноров, отбираем отличные от нуля
M_{{}_{12}}^{{}^{12}}= M_{{}_{13}}^{{}^{12}}= \begin{vmatrix}1&2\\0&2 \end{vmatrix}\!,\quad M_{{}_{24}}^{{}^{12}}= M_{{}_{34}}^{{}^{12}}= \begin{vmatrix}2&0\\2&3\end{vmatrix}\!,\quad M_{{}_{14}}^{{}^{12}}= \begin{vmatrix}1&0\\0&3\end{vmatrix}\!.
Каждый из этих пяти миноров является базисным. Следовательно, ранг матрицы равен 2.
Замечания 3.2
1. Если в матрице все миноры k-го порядка равны нулю, то равны нулю и миноры более высокого порядка. Действительно, раскладывая минор (k+1)-ro порядка по любой строке, получаем сумму произведений элементов этой строки на миноры k-го порядка, а они равны нулю.
2. Ранг матрицы равен наибольшему порядку отличного от нуля минора этой матрицы.
3. Если квадратная матрица невырожденная, то ее ранг равен ее порядку. Если квадратная матрица вырожденная, то ее ранг меньше ее порядка.
4. Для ранга применяются также обозначения \operatorname{Rg}A,~ \operatorname{rang}A,~ \operatorname{rank}A .
5. Ранг блочной матрицы определяется как ранг обычной (числовой) матрицы, т.е. не обращая внимания на ее блочную структуру. При этом ранг блочной матрицы не меньше рангов ее блоков: \operatorname{rg}(A\mid B)\geqslant\operatorname{rg}A и \operatorname{rg}(A\mid B)\geqslant\operatorname{rg}B , поскольку все миноры матрицы A (или B ) являются также минорами блочной матрицы (A\mid B) .
Теоремы о базисном миноре и о ранге матрицы
Рассмотрим основные теоремы, выражающие свойства линейной зависимости и линейной независимости столбцов (строк) матрицы.
Теорема 3.1 о базисном миноре. В произвольной матрице A каждый столбец {строка) является линейной комбинацией столбцов (строк), в которых расположен базисный минор.
Действительно, без ограничения общности предполагаем, что в матрице A размеров m\times n базисный минор расположен в первых r строках и первых r столбцах. Рассмотрим определитель
D=\begin{vmatrix}~ a_{11}&\cdots&a_{1r}\!\!&\vline\!\!&a_{1k}~\\ ~\vdots&\ddots &\vdots\!\!&\vline\!\!&\vdots~\\ ~a_{r1}&\cdots&a_{rr}\!\!&\vline\!\!&a_{rk}~\\\hline ~a_{s1}&\cdots&a_{sr}\!\!&\vline\!\!&a_{sk}~\end{vmatrix},
который получен приписыванием к базисному минору матрицы A соответствующих элементов s-й строки и k-го столбца. Отметим, что при любых 1\leqslant s\leqslant m и этот определитель равен нулю. Если s\leqslant r или k\leqslant r , то определитель D содержит две одинаковых строки или два одинаковых столбца. Если же s>r и k>r , то определитель D равен нулю, так как является минором (r+l)-ro порядка. Раскладывая определитель по последней строке, получаем
a_{s1}\cdot D_{r+11}+\ldots+ a_{sr}\cdot D_{r+1r}+a_{sk}\cdot D_{r+1\,r+1}=0,
где D_{r+1\,j} - алгебраические дополнения элементов последней строки. Заметим, что D_{r+1\,r+1}\ne0 , так как это базисный минор. Поэтому
a_{sk}=\lambda_1\cdot a_{s1}+\ldots+\lambda_r\cdot a_{sr} , где \lambda_j=-\frac{D_{r+1\,j}}{D_{r+1\,r+1}},~j=1,2,\ldots,r.
Записывая последнее равенство для s=1,2,\ldots,m , получаем
\begin{pmatrix}a_{1k}\\\vdots\\a_{mk}\end{pmatrix}= \lambda_1\cdot\! \begin{pmatrix}a_{11}\\\vdots\\a_{m1}\end{pmatrix}+\ldots \lambda_r\cdot\! \begin{pmatrix}a_{1r}\\\vdots\\a_{mr}\end{pmatrix}\!.
т.е. k -й столбец (при любом 1\leqslant k\leqslant n ) есть линейная комбинация столбцов базисного минора, что и требовалось доказать.
Теорема о базисном миноре служит для доказательства следующих важных теорем.
Условие равенства нулю определителя
Теорема 3.2 (необходимое и достаточное условие равенства нулю определителя). Для того чтобы определитель был равен нулю необходимо и достаточно, чтобы один из его столбцов {одна из его строк) был линейной комбинацией остальных столбцов (строк).
В самом деле, необходимость следует из теоремы о базисном миноре. Если определитель квадратной матрицы n-го порядка равен нулю, то ее ранг меньше n , т.е. хотя бы один столбец не входит в базисный минор. Тогда этот выбранный столбец по теореме 3.1 является линейной комбинацией столбцов, в которых расположен базисный минор. Добавляя, при необходимости, к этой комбинации другие столбцы с нулевыми коэффициентами, получаем, что выбранный столбец есть линейная комбинация остальных столбцов матрицы. Достаточность следует из свойств определителя. Если, например, последний столбец A_n определителя \det(A_1~A_2~\cdots~A_n) линейно выражается через остальные
A_n=\lambda_1\cdot A_1+\lambda_2\cdot A_2+\ldots+\lambda_{n-1}\cdot A_{n-1},
то прибавляя к A_n столбец A_1 , умноженный на (-\lambda_1) , затем столбец A_2 , умноженный на (-\lambda_2) , и т.д. столбец A_{n-1} , умноженный на (-\lambda_{n-1}) , получим определитель \det(A_1~\cdots~A_{n-1}~o) с нулевым столбцом, который равен нулю (свойство 2 определителя).
Инвариантность ранга матрицы при элементарных преобразованиях
Теорема 3.3 (об инвариантности ранга при элементарных преобразованиях). При элементарных преобразованиях столбцов (строк) матрицы ее ранг не меняется.
Действительно, пусть . Предположим, что в результате одного элементарного преобразования столбцов матрицы A получили матрицу A" . Если было выполнено преобразование I типа (перестановка двух столбцов), то любой минор (r+l)-ro порядка матрицы A" либо равен соответствующему минору (r+l)-ro порядка матрицы A , либо отличается от него знаком (свойство 3 определителя). Если было выполнено преобразование II типа (умножение столбца на число \lambda\ne0 ), то любой минор (г+l)-ro порядка матрицы A" либо равен соответствующему минору (r+l)-ro порядка матрицы A , либо отличается от него множителем \lambda\ne0 (свойство 6 определителя). Если было выполнено преобразование III типа (прибавление к одному столбцу другого столбца, умноженного на число \Lambda ), то любой минор (г+1)-го порядка матрицы A" либо равен соответствующему минору (г+1) -го порядка матрицы A (свойство 9 определителя), либо равен сумме двух миноров (r+l)-ro порядка матрицы A (свойство 8 определителя). Поэтому при элементарном преобразовании любого типа все миноры (r+l)-ro порядка матрицы A" равны нулю, так как равны нулю все миноры (г+l)-ro порядка матрицы A . Таким образом, доказано, что при элементарных преобразованиях столбцов ранг матрицы не может увеличиться. Так как преобразования, обратные к элементарным, являются элементарными, то ранг матрицы при элементарных преобразованиях столбцов не может и уменьшиться, т.е. не изменяется. Аналогично доказывается, что ранг матрицы не изменяется при элементарных преобразованиях строк.
Следствие 1. Если одна строка (столбец) матрицы является линейной комбинацией других ее строк (столбцов), то эту строку (столбец) можно вычеркнуть из матрицы, не изменив при этом ее ранга.
Действительно, такую строку при помощи элементарных преобразований можно сделать нулевой, а нулевая строка не может входить в базисный минор.
Следствие 2. Если матрица приведена к простейшему виду (1.7), то
\operatorname{rg}A=\operatorname{rg}\Lambda=r\,.
Действительно, матрица простейшего вида (1.7) имеет базисный минор r-го порядка.
Следствие 3. Любая невырожденная квадратная матрица является элементарной, другими словами, любая невырожденная квадратная матрица эквивалентна единичной матрице того же порядка.
Действительно, если A - невырожденная квадратная матрица n-го порядка, то \operatorname{rg}A=n (см. п.З замечаний 3.2). Поэтому, приводя элементарными преобразованиями матрицу A к простейшему виду (1.7), получим единичную матрицу \Lambda=E_n , так как \operatorname{rg}A=\operatorname{rg}\Lambda=n (см. следствие 2). Следовательно, матрица A эквивалентна единичной матрице E_n и может быть получена из нее в результате конечного числа элементарных преобразований. Это означает, что матрица A элементарная.
Теорема 3.4 (о ранге матрицы). Ранг матрицы равен максимальному числу линейно независимых строк этой матрицы.
В самом деле, пусть \operatorname{rg}A=r
. Тогда в матрице A
имеется r
линейно независимых строк. Это строки, в которых расположен базисный минор. Если бы они были линейно зависимы, то этот минор был бы равен нулю по теореме 3.2, а ранг матрицы A
не равнялся бы r
. Покажем, что r
- максимальное число линейно независимых строк, т.е. любые p
строк линейно зависимы при p>r
. Действительно, образуем из этих p
строк матрицу B
. Поскольку матрица B
- это часть матрицы A
, то \operatorname{rg}B\leqslant \operatorname{rg}A=r Значит, хотя бы одна строка матрицы B
не входит в базисный минор этой матрицы. Тогда по теореме о базисном миноре она равна линейной комбинации строк, в которых расположен базисный минор. Следовательно, строки матрицы B
линейно зависимы. Таким образом, в матрице A
не более, чем r
линейно независимых строк. Следствие 1.
Максимальное число линейно независимых строк в матрице равно максимальному числу линейно независимых столбцов:
\operatorname{rg}A=\operatorname{rg}A^T.
Это утверждение вытекает из теоремы 3.4, если ее применить к строкам транспонированной матрицы и учесть, что при транспонировании миноры не изменяются (свойство 1 определителя). Следствие 2.
При элементарных преобразованиях строк матрицы линейная зависимость (или линейная независимость) любой системы столбцов этой матрицы сохраняется.
В самом деле, выберем любые k
столбцов данной матрицы A
и составим из них матрицу B
. Пусть в результате элементарных преобразований строк матрицы A
была получена матрица A"
, а в результате тех же преобразований строк матрицы B
была получена матрица B"
. По теореме 3.3 \operatorname{rg}B"=\operatorname{rg}B
. Следовательно, если столбцы матрицы B
были линейно независимы, т.е. k=\operatorname{rg}B
(см. следствие 1), то и столбцы матрицы B"
также линейно независимы, так как k=\operatorname{rg}B"
. Если столбцы матрицы B
были линейно зависимы (k>\operatorname{rg}B)
, то и столбцы матрицы B"
также линейно зависимы (k>\operatorname{rg}B")
. Следовательно, для любых столбцов матрицы A
линейная зависимость или линейная независимость сохраняется при элементарных преобразованиях строк. Замечания 3.3
1.
В силу следствия 1 теоремы 3.4 свойство столбцов, указанное в следствии 2, справедливо и для любой системы строк матрицы, если элементарные преобразования выполняются только над ее столбцами. 2.
Следствие 3 теоремы 3.3 можно уточнить следующим образом: любую невырожденную квадратную матрицу, используя элементарные преобразования только ее строк (либо только ее столбцов), можно привести к единичной матрице того же порядка.
В самом деле, используя только элементарные преобразования строк, любую матрицу A
можно привести к упрощенному виду \Lambda
(рис. 1.5) (см. теорему 1.1). Поскольку матрица A
невырожденная (\det{A}\ne0)
, то ее столбцы линейно независимы. Значит, столбцы матрицы \Lambda
также линейно независимы (следствие 2 теоремы 3.4). Поэтому упрощенный вид \Lambda
невырожденной матрицы A
совпадает с ее простейшим видом (рис. 1.6) и представляет собой единичную матрицу \Lambda=E
(см. следствие 3 теоремы 3.3). Таким образом, преобразовывая только строки невырожденной матрицы, ее можно привести к единичной. Аналогичные рассуждения справедливы и для элементарных преобразований столбцов невырожденной матрицы. Теорема 3.5 (о ранге произведения матриц).
Ранге произведения и суммы матриц
\operatorname{rg}(A\cdot B)\leqslant \min\{\operatorname{rg}A,\operatorname{rg}B\}.
В самом деле, пусть матрицы A и B имеют размеры m\times p и p\times n . Припишем к матрице A матрицу C=AB\colon\,(A\mid C) . Разумеется, что \operatorname{rg}C\leqslant\operatorname{rg}(A\mid C) , так как C - это часть матрицы (A\mid C) (см. п.5 замечаний 3.2). Заметим, что каждый столбец C_j , согласно операции умножения матриц, является линейной комбинацией столбцов A_1,A_2,\ldots,A_p матрицы A=(A_1~\cdots~A_p):
C_{j}=A_1\cdot b_{1j}+A_2\cdot b_{2j}+\ldots+A_{p}\cdot b_pj},\quad j=1,2,\ldots,n.
Такой столбец можно вычеркнуть из матрицы (A\mid C) , при этом ее ранг не изменится (следствие 1 теоремы 3.3). Вычеркивая все столбцы матрицы C , получаем: \operatorname{rg}(A\mid C)=\operatorname{rg}A . Отсюда, \operatorname{rg}C\leqslant\operatorname{rg}(A\mid C)=\operatorname{rg}A . Аналогично можно доказать, что одновременно выполняется условие \operatorname{rg}C\leqslant\operatorname{rg}B , и сделать вывод о справедливости теоремы.
Следствие. Если A невырожденная квадратная матрица, то \operatorname{rg}(AB)= \operatorname{rg}B и \operatorname{rg}(CA)=\operatorname{rg}C , т.е. ранг матрицы не изменяется приумножении ее слева или справа на невырожденную квадратную матрицу.
Теорема 3.6 о ранге суммы матриц. Ранг суммы матриц не превышает суммы рангов слагаемых:
\operatorname{rg}(A+B)\leqslant \operatorname{rg}A+\operatorname{rg}B.
Действительно, составим матрицу (A+B\mid A\mid B) . Заметим, что каждый столбец матрицы A+B есть линейная комбинация столбцов матриц A и B . Поэтому \operatorname{rg}(A+B\mid A\mid B)= \operatorname{rg}(A\mid B) . Учитывая, что количество линейно независимых столбцов в матрице (A\mid B) не превосходит \operatorname{rg}A+\operatorname{rg}B , a \operatorname{rg}(A+B)\leqslant \operatorname{rg}(A+B\mid A\mid B) (см. п.5 замечаний 3.2), получаем доказываемое неравенство.
Типичное изображение, полученное цифровой фотокамерой, имеет разрешение порядка 3000x2000 , т.е. около 6 мегапикселей; для передачи цвета обычно используется 24 бита на пиксель. Таким образом, объем исходных данных составляет порядка 17 мегабайт . Для профессиональных устройств ввода изображений размер получаемого растра может быть значительно больше, а глубина цвета - достигать 48 бит на пиксель ( "Современные аппаратные средства растровой графики"). Соответственно, размер одного изображения может быть больше 200 мегабайт . Поэтому весьма актуальными являются алгоритмы сжатия изображений, или, иными словами, алгоритмы, которые позволяют уменьшить объем данных, представляющих изображение.
Существуют два основных класса алгоритмов:
- A называется алгоритмом сжатия без потерь (англ. lossless compression ), если существует алгоритм A -1 (обратный к A ) такой, что для любого изображения I A(I) = I 1 и A -1 (I 1) = I . Изображение I задано как множество значений атрибутов пикселей; после применения к I алгоритма A получаем набор данных I 1 . Сжатие без потерь применяется в таких графических форматах представления изображений, как: GIF, PCX , PNG, TGA , TIFF 1Вообще говоря, данный формат также поддерживает сжатие с потерями. , множество собственных форматов от производителей цифровых фотокамер, и т.д.);
- A называется алгоритмом сжатия c потерями (англ. lossy compression ), если он не обеспечивает возможность точного восстановления исходного изображения. Парный к A алгоритм, обеспечивающий примерное восстановление, будем обозначать как A * : для изображения I A(I) = I 1 , A * (I 1) = I 2 и при этом полученное восстановленное изображение I 2 не обязательно точно совпадает с I . Пара A, A * подбирается так, чтобы обеспечить большие коэффициенты сжатия и тем не менее сохранить визуальное качество, т.е. добиться минимальной разницы в восприятии между I и I 2 . Сжатие с потерями применяется в следующих графических форматах: JPEG, JPEG2000 и т.д.
Эта лекция посвящена сжатию без потерь, что требуется в случаях, когда информация была получена большой ценой (например, медицинские изображения или снимки со спутников), либо в других случаях, когда даже малейшие искажения нежелательны .
13.2. Несуществование идеального алгоритма
Как уже было упомянуто в предыдущем пункте, изображение I рассматривается как множество (последовательность) значений атрибутов пикселей. В дальнейшем в этой лекции все алгоритмы и утверждения относятся как к изображениям, так и к произвольным последовательностям, элементы которых могут принимать конечное количество значений.
Утверждение 13.2.1 . Не существует алгоритма, сжимающего без потерь любой набор данных.
Существует 2 N последовательностей размера N битов (будем рассматривать бит как минимальный носитель информации). Пусть найдется алгоритм A такой, что , где |I| - объем данных (длина последовательности). Пусть M = max M k , тогда M < N . Существует 2 1 + 2 2 + ... + 2 M последовательностей длины, меньшей или равной M . Но 2 1 +2 2 +...+2 M = 2 M+1 -2 < 2 N . Противоречие.
Из утверждения следует, что имеет смысл разрабатывать алгоритмы, которые бы эффективно сжимали определенный класс изображений; в то же время для этих алгоритмов всегда будут существовать изображения, для которых они не обеспечат сжатия.
13.3. Алгоритмы кодирования длины повторения (RLE)
Этот тип алгоритмов (алгоритмы кодирования длины повторения 2В литературе часто встречается и другое название - групповое кодирование. (RLE 3англ. Run Length Encoding )) базируется на простейшем принципе: будем заменять повторяющиеся группы элементов исходной последовательности на пару (количество, элемент), либо только на количество.
RLE - битовый уровень
Будем рассматривать исходные данные на уровне последовательности битов; например, представляющих черно-белое изображение. Подряд обычно идет несколько 0 или 1 , и можно помнить лишь количество идущих подряд одинаковых цифр. Т.е. последовательности 0000 11111 000 11111111111 соответствует набор чисел количеств повторений 4 5 3 11 . Возникает следующий нюанс: числа, обозначающие количество повторений, также надо кодировать битами. Можно считать, что каждое число повторений изменяется от 0 до 7 (т.е. можно закодировать ровно тремя битами), тогда последовательности 11111111111 можно сопоставить числа 7 0 4 , т.е. 7 единиц, 0 нулей, 4 единицы. Для примера, последовательность, состоящая из 21 единицы, 21 нуля, 3 единиц и 7 нулей закодируется так: 111 000 111 000 111 111 000 111 000 111 011 111 , т.е. из исходной последовательности, которая имеет длину 51 бит, получили последовательность длиной 36 бит.
Идея этого метода используется при передаче факсов.
RLE - байтовый уровень
Предположим, что на вход подается полутоновое изображение, где на значение интенсивности пикселя отводится 1 байт. Ясно, что по сравнению с черно-белым растром ожидание длинной цепочки одинаковых битов существенно снижается.
Будем разбивать входной поток на байты (буквы) и кодировать повторяющиеся буквы парой (количество, буква).
Т.е. AABBBCDAA кодируем (2A) (3B) (1C) (1D) (2A) . Однако могут встречаться длинные отрезки данных, где ничего не повторяется, а мы кодируем каждую букву парой (цифра, буква).
Пусть у нас есть фиксированное число (буква) M (от 0 до 255 ). Тогда одиночную букву можно закодировать ею самою, - выход = S , а если букв несколько или , то выход = CS , где C > M , а C - M - количество идущих подряд букв S . Для примера приведем только алгоритм декодирования.
// M - фиксированная граница // считываем символы последовательно из входного потока // in - вход - сжатая последовательность // out - выход - разжатая последовательность while(in.Read(c)) { if(c > M) { // случай счетчика n = c - M; in.Read(c); for (i = 0; i < n; i++) out.Write(c); } else // случай просто символа out.Write(c); } Листинг 13.1. Алгоритм декодирования RLE - байтовый уровень
Число M обычно равно 127 . Чаще используется модификация этого алгоритма, где признаком счетчика служит наличие единиц в 2 старших битах считываемого символа. Остальные 6 битов суть значение счетчика.
Такая модификация данного алгоритма используется в формате PCX . Однако модификации данного алгоритма редко используются сами по себе, т.к. подкласс последовательностей, на которых данный алгоритм эффективен, относительно узок. Модификации алгоритма используются как одна из стадий конвейера сжатия (например в формате JPEG,
Алгоритм RLEПервый вариант алгоритма
Данный алгоритм необычайно прост в реализации. Групповое кодирование - от английского Run Length Encoding (RLE) - один из самых старых и самых простых алгоритмов архивации графики. Изображение в нем (как и в нескольких алгоритмах, описанных ниже) вытягивается в цепочку байт по строкам растра. Само сжатие в RLE происходит за счет того, что в исходном изображении встречаются цепочки одинаковых байт . Замена их на пары <счетчик повторений, значение> уменьшает избыточность данных.
Алгоритм декомпрессии при этом выглядит так:
Initialization(...);
do {
if(является счетчиком(byte)) {
counter
= Low6bits(byte)+1;
for(i=1
to counter)
De
}
else {
DecompressedFile.WriteByte(byte)
} while(ImageFile.EOF());
В данном алгоритме признаком счетчика (counter) служат единицы в двух верхних битах считанного файла:
Соответственно оставшиеся 6 бит расходуются на счетчик, который может принимать значения от 1 до 64. Строку из 64 повторяющихся байтов мы превращаем в два байта, т.е. сожмем в 32 раза.
Упражнение: Составьте алгоритм компрессии для первого варианта алгоритма RLE.
Алгоритм рассчитан на деловую графику - изображения с большими областями повторяющегося цвета. Ситуация, когда файл увеличивается, для этого простого алгоритма не так уж редка. Ее можно легко получить, применяя групповое кодирование к обработанным цветным фотографиям. Для того, чтобы увеличить изображение в два раза, его надо применить к изображению, в котором значения всех пикселов больше двоичного 11000000 и подряд попарно не повторяются.Вопрос для самоконтроля: Предложите два-три примера “плохих” изображений для алгоритма RLE. Объясните, почему размер сжатого файла больше размера исходного файла.
Данный алгоритм реализован в формате PCX. См. пример в приложении.Второй вариант алгоритма
Второй вариант этого алгоритма имеет больший максимальный коэффициент архивации и меньше увеличивает в размерах исходный файл.
Алгоритм декомпрессии для него выглядит так:
Initialization(...);
do {
byte = ImageFile.ReadNextByte();
counter = Low7bits(byte)+1;
if(если признак повтора(byte))
{
value
= ImageFile.ReadNextByte();
for (i=1
to counter)
CompressedFile.WriteByte(value)
}
else {
for(i=1 to counter){
value
= ImageFile.ReadNextByte();
CompressedFile.WriteByte(value)
}
CompressedFile.WriteByte(byte)
} while(ImageFile.EOF());
Признаком повтора в данном алгоритме является единица в старшем разряде соответствующего байта:
Как можно легко подсчитать, в лучшем случае этот алгоритм сжимает файл в 64 раза (а не в 32 раза, как в предыдущем варианте), в худшем увеличивает на 1/128. Средние показатели степени компрессии данного алгоритма находятся на уровне показателей первого варианта.
Упражнение: Составьте алгоритм компрессии для второго варианта алгоритма RLE.
Похожие схемы компрессии использованы в качестве одного из алгоритмов, поддерживаемых форматом TIFF, а также в формате TGA.Характеристики алгоритма RLE:
Коэффициенты компрессии: Первый вариант: 32, 2, 0,5. Второй вариант: 64, 3, 128/129. (Лучший, средний, худший коэффициенты)
Класс изображений: Ориентирован алгоритм на изображения с небольшим количеством цветов: деловую и научную графику.
Симметричность: Примерно единица.
Характерные особенности: К положительным сторонам алгоритма, пожалуй, можно отнести только то, что он не требует дополнительной памяти при архивации и разархивации, а также быстро работает. Интересная особенность группового кодирования состоит в том, что степень архивации для некоторых изображений может быть существенно повышена всего лишь за счет изменения порядка цветов в палитре изображения.
Алгоритм LZWНазвание алгоритм получил по первым буквам фамилий его разработчиков - Lempel, Ziv и Welch. Сжатие в нем, в отличие от RLE, осуществляется уже за счет одинаковых цепочек байт.
Алгоритм LZ
Существует довольно большое семейство LZ-подобных алгоритмов, различающихся, например, методом поиска повторяющихся цепочек. Один из достаточно простых вариантов этого алгоритма, например, предполагает, что во входном потоке идет либо пара <счетчик, смещение относительно текущей позиции>, либо просто <счетчик> “пропускаемых” байт и сами значения байтов (как во втором варианте алгоритма RLE). При разархивации для пары <счетчик, смещение> копируются <счетчик> байт из выходного массива, полученного в результате разархивации, на <смещение> байт раньше, а <счетчик> (т.е. число равное счетчику) значений “пропускаемых” байт просто копируются в выходной массив из входного потока. Данный алгоритм является несимметричным по времени, поскольку требует полного перебора буфера при поиске одинаковых подстрок. В результате нам сложно задать большой буфер из-за резкого возрастания времени компрессии. Однако потенциально построение алгоритма, в котором на <счетчик> и на <смещение> будет выделено по 2 байта (старший бит старшего байта счетчика - признак повтора строки / копирования потока), даст нам возможность сжимать все повторяющиеся подстроки размером до 32Кб в буфере размером 64Кб.
При этом мы получим увеличение размера файла в худшем случае на 32770/32768 (в двух байтах записано, что нужно переписать в выходной поток следующие 2 15 байт), что совсем неплохо. Максимальный коэффициент сжатия составит в пределе 8192 раза. В пределе, поскольку максимальное сжатие мы получаем, превращая 32Кб буфера в 4 байта, а буфер такого размера мы накопим не сразу. Однако, минимальная подстрока, для которой нам выгодно проводить сжатие, должна состоять в общем случае минимум из 5 байт, что и определяет малую ценность данного алгоритма. К достоинствам LZ можно отнести чрезвычайную простоту алгоритма декомпрессии.
Упражнение: Предложите другой вариант алгоритма LZ, в котором на пару <счетчик, смещение> будет выделено 3 байта, и подсчитайте основные характеристики своего алгоритма.
Алгоритм LZWРассматриваемый нами ниже вариант алгоритма будет использовать дерево для представления и хранения цепочек. Очевидно, что это достаточно сильное ограничение на вид цепочек, и далеко не все одинаковые подцепочки в нашем изображении будут использованы при сжатии. Однако в предлагаемом алгоритме выгодно сжимать даже цепочки, состоящие из 2 байт.
Процесс сжатия выглядит достаточно просто. Мы считываем последовательно символы входного потока и проверяем, есть ли в созданной нами таблице строк такая строка. Если строка есть, то мы считываем следующий символ, а если строки нет, то мы заносим в поток код для предыдущей найденной строки, заносим строку в таблицу и начинаем поиск снова.
Функция InitTable() очищает таблицу и помещает в нее все строки единичной длины.
InitTable();
CompressedFile.WriteCode(СlearCode);
CurStr=пустая строка;
while(не ImageFile.EOF()){ //Пока не конец файла
C=ImageFile.ReadNextByte();
if(CurStr+C есть в таблице)
CurStr=CurStr+С;//Приклеить
символ к строке
else {
code=CodeForString(CurStr);//code-не
байт!
AddStringToTable
(CurStr+С);
CurStr=С;
// Строка из одного символа
}
}
code=CodeForString(CurStr);
CompressedFile.WriteCode(code);
CompressedFile.WriteCode(CodeEndOfInformation);
Как говорилось выше, функция InitTable() инициализирует таблицу строк так, чтобы она содержала все возможные строки, состоящие из одного символа. Например, если мы сжимаем байтовые данные, то таких строк в таблице будет 256 (“0”, “1”, ... , “255”). Для кода очистки (ClearCode) и кода конца информации (CodeEndOfInformation) зарезервированы значения 256 и 257. В рассматриваемом варианте алгоритма используется 12-битный код, и, соответственно, под коды для строк нам остаются значения от 258 до 4095. Добавляемые строки записываются в таблицу последовательно, при этом индекс строки в таблице становится ее кодом.
Функция ReadNextByte() читает символ из файла. Функция WriteCode() записывает код (не равный по размеру байту) в выходной файл. Функция AddStringToTable() добавляет новую строку в таблицу, приписывая ей код. Кроме того, в данной функции происходит обработка ситуации переполнения таблицы. В этом случае в поток записывается код предыдущей найденной строки и код очистки, после чего таблица очищается функцией InitTable() . Функция CodeForString() находит строку в таблице и выдает код этой строки.
Пример:
Пусть мы сжимаем последовательность 45, 55, 55, 151, 55, 55, 55. Тогда, согласно изложенному выше алгоритму, мы поместим в выходной поток сначала код очистки <256>, потом добавим к изначально пустой строке “45” и проверим, есть ли строка “45” в таблице. Поскольку мы при инициализации занесли в таблицу все строки из одного символа, то строка “45” есть в таблице. Далее мы читаем следующий символ 55 из входного потока и проверяем, есть ли строка “45, 55” в таблице. Такой строки в таблице пока нет. Мы заносим в таблицу строку “45, 55” (с первым свободным кодом 258) и записываем в поток код <45>. Можно коротко представить архивацию так:
- “45” - есть в таблице;
- “45, 55” - нет. Добавляем в таблицу <258>“45, 55”. В поток: <45>;
- “55, 55” - нет. В таблицу: <259>“55, 55”. В поток: <55>;
- “55, 151” - нет. В таблицу: <260>“55, 151”. В поток: <55>;
- “151, 55” - нет. В таблицу: <261>“151, 55”. В поток: <151>;
- “55, 55” - есть в таблице;
- “55, 55, 55” - нет. В таблицу: “55, 55, 55” <262>. В поток: <259>;
Особенность LZW заключается в том, что для декомпрессии нам не надо сохранять таблицу строк в файл для распаковки. Алгоритм построен таким образом, что мы в состоянии восстановить таблицу строк, пользуясь только потоком кодов.
Мы знаем, что для каждого кода надо добавлять в таблицу строку, состоящую из уже присутствующей там строки и символа, с которого начинается следующая строка в потоке.
Алгоритм декомпрессии, осуществляющий эту операцию, выглядит следующим образом:
code=File.ReadCode();
while(code != СodeEndOfInformation){
if(code = СlearСode) {
InitTable();
code=File.ReadCode();
if(code
= СodeEndOfInformation)
{закончить работу};
ImageFile.WriteString(StrFromTable(code));
old_code=code;
}
else {
if(InTable(code))
{
ImageFile.WriteString(FromTable(code));
AddStringToTable(StrFromTable(old_code)+
FirstChar(StrFromTable(code)));
old_code=code;
}
else {
OutString= StrFromTable(old_code)+
FirstChar(StrFromTable(old_code));
ImageFile.WriteString(OutString);
AddStringToTable(OutString);
old_code=code;
}
}
}
Здесь функция ReadCode() читает очередной код из декомпрессируемого файла. Функция InitTable() выполняет те же действия, что и при компрессии, т.е. очищает таблицу и заносит в нее все строки из одного символа. Функция FirstChar() выдает нам первый символ строки. Функция StrFromTable() выдает строку из таблицы по коду. Функция AddStringToTable() добавляет новую строку в таблицу (присваивая ей первый свободный код). Функция WriteString() записывает строку в файл.
Замечание 1
. Как вы могли заметить, записываемые
в поток коды постепенно возрастают. До тех пор, пока в таблице не появится,
например, в первый раз код 512, все коды будут меньше 512. Кроме того,
при компрессии и при декомпрессии коды в таблице добавляются при обработке
одного и того же символа, т.е. это происходит “синхронно”. Мы можем воспользоваться
этим свойством алгоритма для того, чтобы повысить степень компрессии. Пока
в таблицу не добавлен 512 символ, мы будем писать в выходной битовый поток
коды из 9 бит, а сразу при добавлении 512 - коды из 10 бит. Соответственно
декомпрессор также должен будет воспринимать все коды входного потока 9-битными
до момента добавления в таблицу кода 512, после чего будет воспринимать
все входные коды как 10-битные. Аналогично мы будем поступать при добавлении
в таблицу кодов 1024 и 2048. Данный прием позволяет примерно на 15% поднять
степень компрессии:
Замечание 2. При сжатии изображения нам важно обеспечить быстроту поиска строк в таблице. Мы можем воспользоваться тем, что каждая следующая подстрока на один символ длиннее предыдущей, кроме того, предыдущая строка уже была нами найдена в таблице. Следовательно, достаточно создать список ссылок на строки, начинающиеся с данной подстроки, как весь процесс поиска в таблице сведется к поиску в строках, содержащихся в списке для предыдущей строки. Понятно, что такая операция может быть проведена очень быстро.
Заметим также, что реально нам достаточно хранить в таблице только пару <код предыдущей подстроки, добавленный символ>. Этой информации вполне достаточно для работы алгоритма. Таким образом, массив от 0 до 4095 с элементами <код предыдущей подстроки; добавленный символ; список ссылок на строки, начинающиеся с этой строки> решает поставленную задачу поиска, хотя и очень медленно.
На практике для хранения таблицы используется такое же быстрое, как в случае списков, но более компактное по памяти решение - хэш-таблица. Таблица состоит из 8192 (2 13) элементов. Каждый элемент содержит <код предыдущей подстроки; добавленный символ; код этой строки>. Ключ для поиска длиной в 20 бит формируется с использованием двух первых элементов, хранимых в таблице как одно число (key). Младшие 12 бит этого числа отданы под код, а следующие 8 бит под значение символа.
В качестве хэш-функции при этом используется:
Index(key)= ((key >> 12) ^ key) & 8191;
Где >> - побитовый сдвиг вправо (key >> 12 - мы получаем значение символа), ^ - логическая операция побитового исключающего ИЛИ, & логическое побитовое И.
Таким образом, за считанное количество сравнений мы получаем искомый код или сообщение, что такого кода в таблице нет.
Подсчитаем лучший и худший коэффициенты компрессии для данного алгоритма. Лучший коэффициент, очевидно, будет получен для цепочки одинаковых байт большой длины (т.е. для 8-битного изображения, все точки которого имеют, для определенности, цвет 0). При этом в 258 строку таблицы мы запишем строку “0, 0”, в 259 - “0, 0, 0”, ... в 4095 - строку из 3839 (=4095-256) нулей. При этом в поток попадет (проверьте по алгоритму!) 3840 кодов, включая код очистки. Следовательно, посчитав сумму арифметической прогрессии от 2 до 3839 (т.е. длину сжатой цепочки) и поделив ее на 3840*12/8 (в поток записываются 12-битные коды), мы получим лучший коэффициент компрессии.
Упражнение: Вычислить точное значение лучшего коэффициента компрессии. Более сложное задание: вычислить тот же коэффициент с учетом замечания 1.
Худший коэффициент будет получен, если мы ни разу не встретим подстроку, которая уже есть в таблице (в ней не должно встретиться ни одной одинаковой пары символов).Упражнение: Составить алгоритм генерации таких цепочек. Попробовать сжать полученный таким образом файл стандартными архиваторами (zip, arj, gz). Если вы получите сжатие, значит алгоритм генерации написан неправильно.
В случае, если мы постоянно будем встречать новую подстроку, мы запишем в выходной поток 3840 кодов, которым будет соответствовать строка из 3838 символов. Без учета замечания 1 это составит увеличение файла почти в 1.5 раза.LZW реализован в форматах GIF и TIFF.
Характеристики алгоритма LZW:
Коэффициенты компрессии: Примерно1000, 4, 5/7 (Лучший, средний, худший коэффициенты). Сжатие в 1000 раз достигается только на одноцветных изображениях размером кратным примерно 7 Мб.
Класс изображений: Ориентирован LZW на 8-битные изображения, построенные на компьютере. Сжимает за счет одинаковых подцепочек в потоке.
Симметричность: Почти симметричен, при условии оптимальной реализации операции поиска строки в таблице.
Характерные особенности: Ситуация, когда алгоритм увеличивает изображение, встречается крайне редко. LZW универсален - именно его варианты используются в обычных архиваторах.
Алгоритм ХаффманаКлассический алгоритм Хаффмана
Один из классических алгоритмов, известных с 60-х годов. Использует только частоту появления одинаковых байт в изображении. Сопоставляет символам входного потока, которые встречаются большее число раз, цепочку бит меньшей длины. И, напротив, встречающимся редко - цепочку большей длины. Для сбора статистики требует двух проходов по изображению.
Для начала введем несколько определений.
Определение . Пусть задан алфавит Y ={a 1 , ..., a r }, состоящий из конечного числа букв. Конечную последовательность символов из Y
будем называть словом в алфавите Y , а число n - длиной слова A . Длина слова обозначается как l(A).
Пусть задан алфавит W , W ={b 1 , ..., b q }. Через B обозначим слово в алфавите W и через S (W ) - множество всех непустых слов в алфавите W .
Пусть S =S(Y ) - множество всех непустых слов в алфавите Y , и S" - некоторое подмножество множества S . Пусть также задано отображение F , которое каждому слову A, A? S(Y ) , ставит в соответствие слово
B=F(A), B? S(W ) .
Слово В будем назвать кодом сообщения A, а переход от слова A к его коду - кодированием .
Определение . Рассмотрим соответствие между буквами алфавита Y и некоторыми словами алфавита W :
a
1
- B
1
,
a
2
- B
2
,
. . .
a
r
- B
r
Это соответствие называют схемой и обозначают через S . Оно определяет кодирование следующим образом: каждому слову из S" (W ) =S (W ) ставится в соответствие слово , называемое кодом слова A. Слова B 1 ... B r называются элементарными кодами . Данный вид кодирования называют алфавитным кодированием.
Определение . Пусть слово В имеет вид
B=B" B"
Тогда слово B" называется началом или префиксом слова B, а B" - концом слова B. При этом пустое слово L и само слово B считаются началами и концами слова B .
Определение . Схема S обладает свойством префикса, если для любых i и j (1? i , j? r, i? j ) слово B i не является префиксом слова B j .
Теорема 1. Если схема S обладает свойством префикса, то алфавитное кодирование будет взаимно однозначным.
Предположим, что задан алфавит Y ={a 1 ,..., a r } (r >1 ) и набор вероятностей p 1 , . . . , p r появления символов a 1 ,..., a r . Пусть, далее, задан алфавит W , W ={b 1 , ..., b q } (q >1 ). Тогда можно построить целый ряд схем S алфавитного кодирования
a
1
- B
1
,
. . .
a
r
- B
r
обладающих свойством взаимной однозначности.
Для каждой схемы можно ввести среднюю длину l ср , определяемую как математическое ожидание длины элементарного кода:
- длины слов.
Длина l ср показывает, во сколько раз увеличивается средняя длина слова при кодировании со схемой S .
Можно показать, что l ср достигает величины своего минимума l * на некоторой S и определена как
Определение . Коды, определяемые схемой S с l ср = l * , называются кодами с минимальной избыточностью , или кодами Хаффмана.
Коды с минимальной избыточностью дают в среднем минимальное увеличение длин слов при соответствующем кодировании.
В нашем случае, алфавит Y ={a 1 ,..., a r } задает символы входного потока, а алфавит W ={0,1}, т.е. состоит всего из нуля и единицы.
Алгоритм построения схемы S можно представить следующим образом:
Шаг 1. Упорядочиваем все буквы входного алфавита в порядке убывания вероятности. Считаем все соответствующие слова B i из алфавита W ={0,1} пустыми.
Шаг 2. Объединяем два символа a i r-1 и a i r с наименьшими вероятностями p i r-1 и p i r в псевдосимвол a" {a i r-1 a i r } c вероятностью p i r-1 +p i r . Дописываем 0 в начало слова B i r-1 (B i r-1 =0B i r-1 ), и 1 в начало слова B i r (B i r =1B i r ).
Шаг 3. Удаляем из списка упорядоченных символов a i r-1 и a i r , заносим туда псевдосимвол a" {a i r-1 a i r }. Проводим шаг 2, добавляя при необходимости 1 или ноль для всех слов B i , соответствующих псевдосимволам, до тех пор, пока в списке не останется 1 псевдосимвол.
Пример: Пусть у нас есть 4 буквы в алфавите Y ={a 1 ,..., a 4 } (r =4 ), p 1 =0.5, p 2 =0.24, p 3 =0.15, p 4 =0.11 . Тогда процесс построения схемы можно представить так:
Производя действия, соответствующие 2-му шагу, мы получаем псевдосимвол с вероятностью 0.26 (и приписываем 0 и 1 соответствующим словам). Повторяя же эти действия для измененного списка, мы получаем псевдосимвол с вероятностью 0.5. И, наконец, на последнем этапе мы получаем суммарную вероятность 1.
Для того, чтобы восстановить кодирующие слова, нам надо
пройти по стрелкам от начальных символов к концу получившегося бинарного
дерева. Так, для символа с вероятностью p
4
,
получим B
4
=101, для
p
3
получим B
3
=100, для
p
2
получим B
2
=11, для
p
1
получим B
1
=0. Что
означает схему:
a
1
- 0,
a
2
- 11
a
3
- 100
a
4
- 101
Эта схема представляет собой префиксный код, являющийся кодом
Хаффмана. Самый часто встречающийся в потоке символ a
1
мы будем кодировать самым коротким словом 0, а самый редко встречающийся
a
4
длинным словом 101.
Для последовательности из 100 символов, в которой символ a 1 встретится 50 раз, символ a 2 - 24 раза, символ a 3 - 15 раз, а символ a 4 - 11 раз, данный код позволит получить последовательность из 176 бит (). Т.е. в среднем мы потратим 1.76 бита на символ потока.
Доказательства теоремы, а также того, что построенная схема действительно задает код Хаффмана, смотри в .
Как стало понятно из изложенного выше, классический алгоритм Хаффмана требует записи в файл таблицы соответствия кодируемых символов и кодирующих цепочек.
На практике используются его разновидности. Так, в некоторых случаях резонно либо использовать постоянную таблицу, либо строить ее “адаптивно”, т.е. в процессе архивации/разархивации. Эти приемы избавляют нас от двух проходов по изображению и необходимости хранения таблицы вместе с файлом. Кодирование с фиксированной таблицей применяется в качестве последнего этапа архивации в JPEG и в рассмотренном ниже алгоритме CCITT Group 3.
Характеристики классического алгоритма Хаффмана:
Коэффициенты компрессии: 8, 1,5, 1 (Лучший, средний, худший коэффициенты).
Класс изображений: Практически не применяется к изображениям в чистом виде. Обычно используется как один из этапов компрессии в более сложных схемах.
Симметричность: 2 (за счет того, что требует двух проходов по массиву сжимаемых данных).
Характерные особенности: Единственный алгоритм, который не увеличивает размера исходных данных в худшем случае (если не считать необходимости хранить таблицу перекодировки вместе с файлом).
Алгоритм Хаффмана с фиксированной таблицей CCITTGroup 3Близкая модификация алгоритма используется при сжатии черно-белых изображений (один бит на пиксел). Полное название данного алгоритма CCITT Group 3. Это означает, что данный алгоритм был предложен третьей группой по стандартизации Международного Консультационного Комитета по Телеграфии и Телефонии (Consultative Committee International Telegraph and Telephone). Последовательности подряд идущих черных и белых точек в нем заменяются числом, равным их количеству. А этот ряд, уже в свою очередь, сжимается по Хаффману с фиксированной таблицей.
Определение : Набор идущих подряд точек изображения одного цвета называется серией .Длина этого набора точек называется длиной серии .
В таблице, приведенной ниже, заданы два вида кодов:
- Коды завершения серий - заданы с 0 до 63 с шагом 1.
- Составные (дополнительные) коды - заданы с 64 до 2560 с шагом 64.
На практике в тех случаях, когда в изображении преобладает черный цвет, мы инвертируем изображение перед компрессией и записываем информацию об этом в заголовок файла.
Алгоритм компрессии выглядит так:
for(по всем строкам изображения) {
Преобразуем строку в набор длин
серий;
for(по всем сериям) {
if(серия
белая) {
L= длина серии;
while(L > 2623) { // 2623=2560+63
L=L-2560;
ЗаписатьБелыйКодДля(2560);
}
if(L > 63) {
L2=МаксимальныйСостКодМеньшеL(L);
L=L-L2;
ЗаписатьБелыйКодДля(L2);
}
ЗаписатьБелыйКодДля(L);
//Это всегда код завершения
}
else {
[Код аналогичный белой серии,
с той разницей, что записываются
черные коды]
}
}
// Окончание строки изображения
}
Поскольку черные и белые серии чередуются, то реально код для белой и код для черной серии будут работать попеременно.
В терминах регулярных выражений мы получим для каждой строки нашего изображения (достаточно длинной, начинающейся с белой точки) выходной битовый поток вида:
((<Б-2560>)*[<Б-сст.>]<Б-зв.>(<Ч-2560>)*[<Ч-сст.>]<Ч-зв.>) +
[(<Б-2560>)*[<Б-сст.>]<Б-зв.>]
Где ()* - повтор 0 или более раз, () + .- повтор 1 или более раз, - включение 1 или 0 раз.
Для приведенного ранее примера: 0, 3, 556, 10... алгоритм сформирует следующий код: <Б-0><Ч-3><Б-512><Б-44><Ч-10>, или, согласно таблице, 0011010110 0110010100101101 0000100 (разные коды в потоке выделены для удобства). Этот код обладает свойством префиксных кодов и легко может быть свернут обратно в последовательность длин серий. Легко подсчитать, что для приведенной строки в 569 бит мы получили код длиной в 33 бита, т.е. коэффициент сжатия составляет примерно 17 раз.
Вопрос: Во сколько раз увеличится размер файла в худшем случае? Почему? (Приведенный в характеристиках алгоритма ответ не является полным, поскольку возможны большие значения худшего коэффициента сжатия. Найдите их.)
Заметим, что единственное “сложное” выражение в нашем алгоритме: L2=МаксимальныйДопКодМеньшеL(L) - на практике работает очень просто: L2=(L>>6)*64, где >> - побитовый сдвиг L влево на 6 битов (можно сделать то же самое за одну побитовую операцию & - логическое И).Упражнение: Дана строка изображения, записанная в виде длин серий - 442, 2, 56, 3, 23, 3, 104, 1, 94, 1, 231, размером 120 байт ((442+2+..+231)/8). Подсчитать коэффициент компрессии этой строки алгоритмом CCITT Group 3.
Приведенные ниже таблицы построены с помощью классического алгоритма Хаффмана (отдельно для длин черных и белых серий). Значения вероятностей появления для конкретных длин серий были получены путем анализа большого количества факсимильных изображений.Таблица кодов завершения:
Длина
серии |
Код белой
подстроки |
Код черной
подстроки |
Длина
серии |
Код белой
подстроки |
Код черной
подстроки |
|
0 | 00110101 | 0000110111 | 32 | 00011011 | 000001101010 | |
1 | 00111 | 010 | 33 | 00010010 | 000001101011 | |
2 | 0111 | 11 | 34 | 00010011 | 000011010010 | |
3 | 1000 | 10 | 35 | 00010100 | 000011010011 | |
4 | 1011 | 011 | 36 | 00010101 | 000011010100 | |
5 | 1100 | 0011 | 37 | 00010110 | 000011010101 | |
6 | 1110 | 0010 | 38 | 00010111 | 000011010110 | |
7 | 1111 | 00011 | 39 | 00101000 | 000011010111 | |
8 | 10011 | 000101 | 40 | 00101001 | 000001101100 | |
9 | 10100 | 000100 | 41 | 00101010 | 000001101101 | |
10 | 00111 | 0000100 | 42 | 00101011 | 000011011010 | |
11 | 01000 | 0000101 | 43 | 00101100 | 000011011011 | |
12 | 001000 | 0000111 | 44 | 00101101 | 000001010100 | |
13 | 000011 | 00000100 | 45 | 00000100 | 000001010101 | |
14 | 110100 | 00000111 | 46 | 00000101 | 000001010110 | |
15 | 110101 | 000011000 | 47 | 00001010 | 000001010111 | |
16 | 101010 | 0000010111 | 48 | 00001011 | 000001100100 | |
17 | 101011 | 0000011000 | 49 | 01010010 | 000001100101 | |
18 | 0100111 | 0000001000 | 50 | 01010011 | 000001010010 | |
19 | 0001100 | 00001100111 | 51 | 01010100 | 000001010011 | |
20 | 0001000 | 00001101000 | 52 | 01010101 | 000000100100 | |
21 | 0010111 | 00001101100 | 53 | 00100100 | 000000110111 | |
22 | 0000011 | 00000110111 | 54 | 00100101 | 000000111000 | |
23 | 0000100 | 00000101000 | 55 | 01011000 | 000000100111 | |
24 | 0101000 | 00000010111 | 56 | 01011001 | 000000101000 | |
25 | 0101011 | 00000011000 | 57 | 01011010 | 000001011000 | |
26 | 0010011 | 000011001010 | 58 | 01011011 | 000001011001 | |
27 | 0100100 | 000011001011 | 59 | 01001010 | 000000101011 | |
28 | 0011000 | 000011001100 | 60 | 01001011 | 000000101100 | |
29 | 00000010 | 000011001101 | 61 | 00110010 | 000001011010 | |
30 | 00000011 | 000001101000 | 62 | 00110011 | 000001100110 | |
31 | 00011010 | 000001101001 | 63 | 00110100 | 000001100111 |
Таблица составных кодов:
Длина
серии |
Код белой
подстроки |
Код черной
подстроки |
Длина
серии |
Код белой
подстроки |
Код черной
подстроки |
|
64 | 11011 | 0000001111 | 1344 | 011011010 | 0000001010011 | |
128 | 10010 | 000011001000 | 1408 | 011011011 | 0000001010100 | |
192 | 01011 | 000011001001 | 1472 | 010011000 | 0000001010101 | |
256 | 0110111 | 000001011011 | 1536 | 010011001 | 0000001011010 | |
320 | 00110110 | 000000110011 | 1600 | 010011010 | 0000001011011 | |
384 | 00110111 | 000000110100 | 1664 | 011000 | 0000001100100 | |
448 | 01100100 | 000000110101 | 1728 | 010011011 | 0000001100101 | |
512 | 01100101 | 0000001101100 | 1792 | 00000001000 | совп. с белой | |
576 | 01101000 | 0000001101101 | 1856 | 00000001100 | - // - | |
640 | 01100111 | 0000001001010 | 1920 | 00000001101 | - // - | |
704 | 011001100 | 0000001001011 | 1984 | 000000010010 | - // - | |
768 | 011001101 | 0000001001100 | 2048 | 000000010011 | - // - | |
832 | 011010010 | 0000001001101 | 2112 | 000000010100 | - // - | |
896 | 011010011 | 0000001110010 | 2176 | 000000010101 | - // - | |
960 | 011010100 | 0000001110011 | 2240 | 000000010110 | - // - | |
1024 | 011010101 | 0000001110100 | 2304 | 000000010111 | - // - | |
1088 | 011010110 | 0000001110101 | 2368 | 000000011100 | - // - | |
1152 | 011010111 | 0000001110110 | 2432 | 000000011101 | - // - | |
1216 | 011011000 | 0000001110111 | 2496 | 000000011110 | - // - | |
1280 | 011011001 | 0000001010010 | 2560 | 000000011111 | - // - |
Этот алгоритм реализован в формате TIFF.
Характеристики алгоритма CCITT Group 3