П/2N)* cos((2y+1)jП/2N);=0 j-0
Здесь C(i) и C(j) равны 1/sqr(2) для i,j=0 и C(i), C(j)=1 при i,j>0;(x,y) - значение отсчета яркости пиксела фрагмента изображения с координатами x и y.
Для начала следует создать ДКП матрицу, используя формулу:
= 1/sqr(N), если i=0= sqr(2/N)*cos[(2j+1)*i*3.14/2N], если i > 0= 8, 0 < i < 7, 0 < j < 7
в результате имеем:
|.353553.353553.353553.353553.353553.353553.353553.353553|
|.490393.415818.277992.097887 -.097106 -.277329 -.415375 -.490246|
|.461978.191618 -.190882 -.461673 -.462282 -.192353.190145.461366|= |.414818 -.097106 -.490246 -.278653.276667.490710.099448 -.414486|
|.353694 -.353131 -.354256.352567.354819 -.352001 -.355378.351435|
|.277992 -.490246.096324.416700 -.414486 -.100228.491013 -.274673|
|.191618 -.462282.461366 -.189409 -.193822.463187 -.460440.187195|
|.097887 -.278653.416700 -.490862.489771 -.413593.274008 -.092414|
например, нам нужно сжать следующий фрагмент изображения:
| 95 88 88 87 95 88 95 95|
|153 151 162 166 162 151 126 117|= |143 144 133 130 143 153 159 175|
|123 112 116 130 143 147 162 189|
|133 151 162 166 170 188 166 128|
|160 168 166 159 135 101 93 98|
|154 155 153 144 126 106 118 133|
|-33 -40 -40 -41 -33 -40 -33 -33|
| 15 16 23 23 25 42 55 53|
| 25 23 34 38 34 23 -2 -11|= | 15 16 5 2 15 25 31 47|
| -5 -16 -12 2 15 19 34 61|
| 5 23 34 38 42 60 38 0|
| 32 40 38 31 7 -27 -35 -30|
| 26 27 25 16 -2 -22 -10 5|
вот формула, по которой производится ДКП: RES*IMG*DCT
для начала нужно посчитать промежуточную матрицу: TMP = IMG*DCT
|-103 -3 1 2 4 0 -1 5|
| 89 -40 12 -2 -7 5 1 0|
| 57 31 -30 6 2 0 5 0|= | 55 -28 24 1 0 -8 0 0|
| 32 -60 18 -1 14 0 -8 1|
| 84 -11 -37 17 -24 4 0 -4|
| 19 81 -16 -20 8 -3 4 0|
| 22 40 11 -22 8 0 -3 2|
затем умножаем ее на ДКП матрицу: RES = TMP*DCT
| 91 3 -5 -6 2 0 1|
|-38 -57 9 17 -2 2 2|
|-80 58 0 -18 4 3 4|= |-52 -36 -11 13 -9 3 0|
|-86 -40 44 -7 17 -6 4|
|-62 64 -13 -1 3 -8 0|
|-16 14 -35 17 -11 2 -1|
|-53 32 -9 -8 22 0 2|
Этап 2. Квантование
На этом этапе мы посчитаем матрицу квантования, используя этот псевдокод:
(i=0;i<8;i++)
{(j=0;j<8;j++)[i][j] = 1+((1+i+j)*q);
}
где q - это коэффициент качества, задаваемый пользователем, от него зависит степень потери качества сжатого изображения. Величину этого коэффициента рекомендуется выбирать в диапазоне от1 до 25. большие значения коэффициента качества также возможны, однако при качество воспроизводимого изображения резко ухудшается.
Так для q = 2 имеем матрицу квантования:
| 3 5 7 9 11 13 15 17|
| 5 7 9 11 13 15 17 19|
| 7 9 11 13 15 17 19 21|= | 9 11 13 15 17 19 21 23|
|11 13 15 17 19 21 23 25|
|13 15 17 19 21 23 25 27|
|15 17 19 21 23 25 27 29|
|17 19 21 23 25 27 29 31|
теперь нужно каждое число в матрице квантования разделить на число в соответствующей позиции в матрице RES, в результате получим:
| 30 0 0 0 0 0 0 0|
| -7 8 1 1 0 0 0 0|
|-11 6 0 1 0 0 0 0|= | -5 -3 0 0 0 0 0 0|
| -7 -3 2 0 0 0 0 0|
| -4 4 0 0 0 0 0 0|
| -1 0 1 0 0 0 0 0|
| -3 1 0 0 0 0 0 0|
как вы видите, здесь имеется довольно много нулей, мы получим наиболее длинную последовательность нулей, если будем использовать следующий алгоритм:
+----+----+----+----+----+----+----+----+
| 1 | 2 | 6 | 7 | 15 | 16 | 28 | 29 |
+----+----+----+----+----+----+----+----+
| 3 | 5 | 8 | 14 | 17 | 27 | 30 | 43 |
+----+----+----+----+----+----+----+----+
| 4 | 9 | 13 | 18 | 26 | 31 | 42 | 44 |
+----+----+----+----+----+----+----+----+
| 10 | 12 | 19 | 25 | 32 | 41 | 45 | 54 |
+----+----+----+----+----+----+----+----+
| 11 | 20 | 24 | 33 | 40 | 46 | 53 | 55 |
+----+----+----+----+----+----+----+----+
| 21 | 23 | 34 | 39 | 47 | 52 | 56 | 61 |
+----+----+----+----+----+----+----+----+
| 22 | 35 | 38 | 48 | 51 | 57 | 60 | 62 |
+----+----+----+----+----+----+----+----+
| 36 | 37 | 49 | 50 | 58 | 59 | 63 | 64 |
+----+----+----+----+----+----+----+----+
итак, у нас получилась последовательность:
0 0 0 0 0 0 -3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
для большего сжатия можно перед первым этапом JPEG можно провести субдискретизацию, или другими словами уменьшить частоту изображения,идея очень проста: к примеру у нас есть следующая последовательность
42 200 123 56 32 125 234 12 24 34 78 145 134 245 101
если будем использовать субдискретизацию 4:1:1 результирующая последовательность будет: 11 123 125 24 145 101
а если использовать 4:2:2 - 11 234 245
а для восстановления последовательности нужно интерполироать
Этап 3. Вторичное сжатие
На этом этапе можно применить следующий алгоритм 7bit RLE.Этот алгоритм очень прост. Если у нас есть последовательность одинаковых байтов, то нужно установить последний бит в 0, посчитать количество байт и записать в оставшиеся биты. Если у нас последовательность различных байтов, то нужно установить последний быт в 1, посчитать количество байт и записать его в оставшиеся биты. Для нашей последовательности получится:
30 0 -7 -11 8 | 2 0 | 135 1 6 -5 -7 -3 0 1 | 3 0 | 135 1 0 -3 -4 -1 4 2
0 | 131 -3 1 1 | 27 0
итак, мы сжали 64 байта в 34
. Описание метода jpeg
Для обобщения опыта разработки и использования методов сжатия неподвижных полутоновых и цветных изображений и разработки международного стандарта МККТТ и МОС в 1991 году была создана организация, состоящая из группы экспертов, которая получила название JPEG (Join Photographic Expert Group). Разработанный ими стандарт алгоритма обработки изображений получил название JPEG, который определяет правила сжатия многоградационных как черно-белых, так и цветных и полутоновых изображений. Стандарт состоит из ряда частей, включающих как сжатие без потерь, так и с частичными искажениями преобразуемой информации. Компрессия без потерь базируется на основе ДИКМ с предсказанием, адаптивных алгоритмов Хаффмена или арифметического кодирования. Компрессия изображений с потерей использует метод косинусного преобразования с последующим квантованием.
Вносимые искажения информации при ее компрессии в соответствии в алгоритмом JPEG не должны приводить к заметному ухудшению качества восстанавливаемого изображения, в частности, качество изображения по сравнению с оригиналов должно оцениваться на «отлично» или «хорошо». Кроме этого метод должен быть достаточно простым в реализации.
Структура компрессора и декомпрессора видеоинформации по стандарту JPEG показана на рисунке 1:
Фрагмент изображения
Восстановленный фрагмент
Рисунок 1 - Структурная схема компрессора и декомпрессора по JPEG
Рассмотрим подробнее некоторые особенности процедуры обработки изображений JPREG. Кодируемое изображение разбивается на блоки размером 8*8 элементов (пикселей). Каждый блок представляет собой 64-точечный дискркетный сигнал, состоящий из последовательности целых чисел в диапазоне [0.. 2^k - 1], которые затем преобразовываются в знаковые числа диапазона [-2^k, 2^(k-1) - 1]. Так, при256 градациях яркости количество разрядов для кодирования отсчета изображения k=8. Яркость пикселя путем масштабирования переносится из интервала 0 - 255 в диапазон от -127 до 127.
Выходной сигнал блока FDCT представляет собой 64-элементный массив, организованный в матрицу 8*8. Амплитуды трансформант однозначно определяются исходным блоком отчетов видеосигнала, и представляет собой коэффициенты при дискретных частотах. Коэффициент при нулевой частоте определяет амплитуду постоянной составляющей (DC), а остальные коэффициенты - амплитуды переменных составляющих (AC). В связи с тем, что элементы изображения во входном блоке изменяются слабо, то за счет косинусного преобразования удается сгруппировать трансформанты в области нижних пространственных частот. Следует еще раз подчеркнуть, что косинусное преобразование является обратимым и не приводит к сжатия сообщения. Оно осуществляет только подготовку данных к процедуре сжатия, которая осуществляется в квантователе.
Целью квантования является компрессия изображения путем задания точности не большей, чем это необходимо для получения желаемого качества воспроизведения изображения. При сжатии трансформант можно снижать и точность квантования, причем тем больше, чем дальше расположена трансформанта от постоянной составляющей DC, находящейся в матрице с индексами (0,0). Снижение точности отображения трансформант уменьшает количество требуемых для их представления битов. Элементы, которые расположены ближе к постоянной составляющей, кодируются большим числом битов, а более удаленные - меньшим.
В алгоритме JPEG операция квантования реализуется с помощью матрицы квантования. Для каждого элемента матрицы трансформант имеется соответствующие ему значения кванта Q(i,j), расположенные в матрице квантования. Квантование осуществляется делением каждой трансформанты F(i,j) на соответствующий ей квант Q(i, j) и выделением целой части.
Fq(i, j) = [ F(i, j) / Q(i, j) ]
Значение Q(i, j) находится в диапазоне от 0 до 255. Величина Q(i, j)=1 обеспечивает наибольшую точность.По мере удаления от верхнего левого угла матрицы значение квантов увеличивается. Нетрудно заметить, что, начиная с некоторых значений, когда Q(i, j)> F(i, j) квантованное значение Fq(i, j) обращается в нуль, т.е. происходит невозвратимая потеря части информации. Несмотря на наличие стандартной таблицы квантов, JPEG предоставляет пользователям определенную свободу выбора элементов матрицы квантов в зависимости от желаемого качества воспроизведения. Предложено определять значения квантов по формуле
[ i, j ]=1+(1+i+j)*g,
Где i и j - индексы элементов матрицы квантов, при i,j=1,2,…,N; g-коэффициент качества воспроизведения изображения, задаваемого пользователем. Величину этого коэффициента рекомендуется выбирать в диапазоне от 1 до 25. Большие значения коэффициента качества также возможны, однако при этом качество воспроизводимого изображения резко ухудшается. В таблице представлена матрица квантов, рассчитанная при коэффициенте качества g=2.
Коэффициенты квантования Q(i, j)3579111315175791113151719791113151719219111315171921231113151719212325131517192123252715171921232527291719212325272931
При деквантовании производится операция умножения, т.е.
F(i, j) =Fq (i, j)* Q(i, j)
Величина F(i,j) является входной для обратного косинусного преобразования. В, в качестве примера, приведены значения трансформант на выходе косинусного преобразователя произвольного фрагмента изображения, а в следующей таблице - значения на выходе квантователя. В связи с тем, что многие трансформанты приобретают нулевое значение, объем передаваемой информации существенно уменьшится.
Значения трансформант перед квантованием923 -9-73-102-39-581217-2242-84621-1834-55-52-36-1014-104-20-86-4049-717-6-25-6265-12-23-8-20-1714-3617-1133-1-5432-9922013Значения трансформант после деквантования900-700000-35-569110000-84540-130000-45-33000000-77-394500000-5260000000-150-1900000-5119000000
Дальнейшим шагом JPEG-процедуры является кодирование квантованного изображения. Сначала разделяются трансформанты постоянной DC и переменной AC составляющих. Трансформанта постоянной составляющей является мерой среднего значения 63 отсчетов изображения. Так как соседние блоки изображения обычно имеют сильную корреляционную связь, то постоянная составляющая последующего блока в большинстве случаев мало отличается от DC - составляющей предыдущего блока. Она преобразуется из абсолютного значения в относительное, и затем кодируется приращение текущей DC - составляющей по отношению к предыдущей (ДИКМ).
Трансформанты переменных составляющих преобразуются в последовательность способом «Зигзаг». Последовательность трансформант AC можно считать методом кодирования длин повторяющихся символов (так как в образованной последовательности имеется большое число нулей), либо хаффменовским или арифметическим кодированием.
Схема считывания отсчетов фрагмента изображения
0.0 0.1 0.2 1.01.11.22.02.12.23.03.13.24.04.14.25.05.15.26.06.16.26.37.07.17.27.3
Для сжатия последовательности AC-трансформант фрагмента изображения рекомендуется использовать так называемое энтропийное кодирование. При этом способе амплитуды ненулевых АС - составляющих отображаются неравномерным кодом, не обладающим свойством разделимости кодовых комбинаций. Поэтому для их разделения перед каждой из комбинаций ставится индикатор, указывающий длину текущей кодовой комбинации. Длинные группы нулей, расположенные между ненулевыми трансформантами, сжимаются методом кодирования длин последовательности одинаковых символов. В соответствии с рекомендацией JPEG отрезки зигзаг-последовательности, состоящие из группы нулевых и одной ненулевой трансформант, кодируются двумя словами: СИМ1 и СИМ2. СИМ1 представлен одним байтом, старший полубайт которого указывает длину ряда нулевых трансформант кодируемого отрезка, а младший - размер (количество битов) второго символа СИМ2, отображающего амплитуду ненулевой трансформанты, завершающую отрезок последовательности нулевых трансформант. Очевидно, что полубайт может закодировать длину отрезка, состоящего из 1..15 нулевых трансформант. На практике длина отрезка может быть больше 15. В этом случае длинная последовательность нулей представляется СИМ1 (15,0), отображающим группу, состоящую из 16 нулей. Таких символов при величине кодируемого фрагмента изображения 8*8 может быть до 3-х. Затем следует СИМ2 с кодом длины, дополняющей последовательность до действительного числа нулевых трансформант. Значение символа СИМ1 с кодом (0,0) используется для индикации конца кодирования текущего фрагмента отсчетов размером 8*8 элементов. Для кодирования амплитуды ненулевых трансформант используются целые двоичные знаковые числа, содержащие различное число битов.
Количество битовЗначение амплитуды1-1,12От -3 до -2, от 2 до 3 3От-7 до -4, от 4 до74От -15 до -8, от8 до 155От -31 до -16, от 16 до 316От -63 до -32, от 32 до 637От -127 до -64, от 64 до 1278От -255 до -128, от 128 до 2559От -511 до -256, от 256 до 51110От -1023 до -512, от 512 до 1023
Каждая группа битов кодирует симметричный диапазон амплитуд, состоящий из положительных и отрицательных значений. Старший бит этих чисел отображает знак, а остальные - значение амплитуды. Постоянная составляющая трансформант DC также кодируется неравномерным кодом и представляется посредством двух символов. Первый символ СИМ1 указывает длину, а второй СИМ2 - амплитуду DC - составляющей. В связи с тем, что постоянные составляющие кодируются дифференциальным способом, диапазон их представления увеличивается вдвое и изменяется от -2^11 до 2^11-1. Поэтому добавляется дополнительная строка, а СИМ2 принимает значение от 0 до 11. Такой неравномерный код по степени сжатия несколько уступает хаффменскому или арифметическим кодам. Однако он значительно проще в реализации и является достаточно эффективным, когда большинство трансформант состоит из малых значений, что чаще всего наблюдается на практике.
В процессе исследований процедуры сжатия установлено, что кодовые комбинации СИМ1, отображающие длину нулевых последовательностей и амплитуду трансформант, характеризуются большой неравномерностью вероятности появления. Поэтому JPEG рекомендует производить дополнительное сжатие информации путем хаффменовского кодирования символов СИМ1.
Пример. Закодировать способом энтропийного кодирования проквантованные трансформанты блока, приведенного в таблице.
Значения трансформант после квантования86-530020112-3000000-11700020000100000021000000000000000070000000000000
Последовательность значений трансформант:
-5 12 -1 -3 3 0 0 17 0 0 0 0 0 0 2 0 0 -1 0 21 0 0 0 0 0 0 0 0 -1 0 -2 0 0 0 0 0 0 -7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.
Используя описанный выше способ кодирования и данные таблицы, получим последовательность символов СИМ1 и СИМ2:
(7)(86) (0,3)(-5) (0,4)(12) (0,1)(-1) (0,2)(-3) (2,5)(17) (6,2)(2) (2,1)(-1) (0,5)(21) (8,1)(-1) (1,2)(-2) (6,3)(-7) (0,0)
jpeg полутоновое изображение сжатие компрессия
Рассмотренный JPEG-алгоритм относится к монохромным изображениям. Цветные изображения обычно состоят из трех компонент: красного, зеленого и синего цветов (RGB-формат сигнала). В этом случае JPEG-алгоритм рассматривает изображение так, как будто оно состоит из трех отдельных изображений. При RGB-изображении сначала сжимается красная, затем зеленая и в конце синяя компонента. Для каждой компоненты могут использоваться различные таблицы квантования и энтропийного кодирования, которые определяются статистическими характеристиками составляющих изображения. В процессе компрессии и декомпрессии осуществляется синхронное переключение таблиц в соответствии с обрабатываемой компонентой.
6. Тестирование программы
При тестировании программы получено полутоновое неподвижное изображение, которое находится на одном из окон программы. Субъективная оценка работы программы - «хорошо».
Заключение
Данная программа разработана в соответствии с постановкой задачи на курсовое проектирование по теме "Компрессия полутонового изображения" по дисциплине "Кодирование и защита информации" («КиЗИ»). При написании программы использованы методические указания по курсовому проектированию по дисциплине "КиЗИ". Интерфейс программы удобен для использования. Выходные данные представлены в виде полутонового неподвижного изображения на одном из окон программы. По своей структуре программа хорошо организована, что позволяет в случае необходимости легко ее модифицировать. Для проверки работоспособности программы и правильности обработки входных данных разработан тестовый пример. Тестирование программы подтвердило, что программа правильно выполняет обработку данных и выдаёт верные результаты.
Всё это свидетельствует о работоспособности программы и позволяет сделать вывод о пригодности программы к компрессии полутонового изображения и является наглядным примером программной реализации метода JPEG.
Библиографический список
1. В.С.Чернега Сжатие информации в компьютерных сетях: Учебное пособие для вузов: Под ред. д.т.н., проф. В.К. Маригодова.- Севастополь.: СевГТУ,- 1997.-214с.: ил.
Приложение
Unit1;, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,, ExtDlgs, ExtCtrls, StdCtrls, Buttons, Spin, Grids;
{****}=Record:Array[1..2] Of Char;:Integer;:Integer;:Integer;:Integer;:Integer;:Integer;:Word;:Word;:Integer;:Integer;:Integer;:Integer;:Integer;:Integer;
{****}= class(TForm): TMainMenu;: TOpenDialog;: TMenuItem;: TMenuItem;: TMenuItem;: TMenuItem;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TBevel;: TBevel;: TBevel;: TSpeedButton;: TLabel;: TSpeedButton;: TEdit;: TSpeedButton;: TSpinEdit;: TLabel;: TLabel;Open1Click(Sender: TObject);CompressionClick(Sender: TObject);DecompressionClick(Sender: TObject);ConvertClick(Sender: TObject);Exit1Click(Sender: TObject);ToBinTo(Digit:SmallInt;N:ShortInt);ToBin(Digit:SmallInt;N:ShortInt);Int24ToInt3_8(Digit:Integer;x,y:ShortInt);GetColor(x,y:ShortInt);PutColor(x,y:ShortInt);ConvertWrite(x,y:Integer);ToCos;CosTo;TKwant;ToKwant;KwantTo;TR(var x,y: Integer;S: ShortInt);TD(var x,y: Integer;S: ShortInt);TLD(var x,y: Integer;S: ShortInt);TRU(var x,y: Integer;S: ShortInt);Zigzag(Style: ShortInt);Coding;ChoiceAmp(Digit:SmallInt);BinToSym1Dec;BinToSym2Dec;Decoding;RabFileToLongInt;LongIntToRabFile;
{ Private declarations }
{ Public declarations };: TForm1;: TPImage;: Array[0..7,0..7] Of Byte;: Array[0..7,0..7] Of Integer;: Array[0..63] Of Integer;: Array[0..7,0..7] Of Integer;: Array[0..7,0..7] Of Integer;: TextFile;: Byte;,Sym12,Sym2: Integer;: Array [0..191] Of Integer;: String;: Integer;: integer;: String;Unit2;
{$R *.DFM}TForm1.Exit1Click(Sender: TObject);.Close;;TForm1.Open1Click(Sender: TObject);F:File;,j:integer;: Byte;OpenDialog1.Execute Then Begin(F,OpenDialog1.FileName);(F,1);PImage Do Begin(F,bfType,SizeOF(bfType));.Label16.Caption:=bfType;(F,bfSize,SizeOF(bfSize));.Label17.Caption:=IntToStr(bfSize)+' bytes';(F,bfReserved,SizeOF(bfReserved));.Label18.Caption:=IntToStr(bfReserved);(F,bfOffBits,SizeOF(bfOffBits));.Label19.Caption:=IntToStr(bfOffBits)+' bytes';(F,biSize,SizeOF(biSize));.Label20.Caption:=IntToStr(biSize);(F,biWidth,SizeOF(biWidth));.Label21.Caption:=IntToStr(biWidth);(F,biHeight,SizeOF(biHeight));.Label22.Caption:=IntToStr(biHeight);(F,biPlanes,SizeOF(biPlanes));.Label23.Caption:=IntToStr(biPlanes);(F,biBitCount,SizeOF(biBitCount));.Label24.Caption:=IntToStr(biBitCount);(F,biCompression,SizeOF(biCompression));.Label25.Caption:=IntToStr(biCompression);(F,biSizeImage,SizeOF(biSizeImage));.Label26.Caption:=IntToStr(biSizeImage);(F,biXPelsPerMeter,SizeOF(biXPelsPerMeter));.Label27.Caption:=IntToStr(biXPelsPerMeter);(F,biYPelsPerMeter,SizeOF(biYPelsPerMeter));.Label28.Caption:=IntToStr(biYPelsPerMeter);(F,biClrUsed,SizeOF(biClrUsed));.Label29.Caption:=IntToStr(biClrUsed);(F,biClrImpotant,SizeOF(biClrImpotant));.Label30.Caption:=IntToStr(biClrImpotant);:=0;i:=1 to biWidth do Beginj:=1 to biHeight do.Image1.Canvas.Pixels[j,i]:= (red or Form2.Image1.Canvas.Pixels[j,i]);;;(F);.Enabled:=True;.Width:=PImage.biWidth+10;.Height:=PImage.biHeight+10;.Image1.Picture.LoadFromFile(Form1.OpenDialog1.FileName);.Image1.Width:=PImage.biWidth+6;.Image1.Height:=PImage.biHeight+23;.Visible:=True;;
{***********************************************************}TForm1.ConvertWrite(x,y:Integer);i,j: integer;i:=0 to 7 do beginj:=0 to 7 do begin.Image1.Canvas.Pixels[x*8+i,y*8+j]:=RGB(clRGB[i,j],clRGB[i,j],clRGB[i,j]);;;;TForm1.ConvertClick(Sender: TObject);i,j,x,y: integer;: Byte;x:=0 To Trunc((PImage.biWidth+1)/8) Doy:=0 To Trunc((PImage.biHeight+1)/8) Do(x,y);(x,y);;.Image1.Picture.SaveToFile('c:\ConvertFile.bmp');;
{***********************************************************}
{***********************************************************}TForm1.Int24ToInt3_8(Digit:Integer;x,y:ShortInt);i,j:ShortInt;:Byte;:=0;j:=0 To 7 Do Begin IF (Digit Mod 2)=1 Then k:=k+Trunc(exp(j*Ln(2)));:=Digit Div 2;[x,y]:=k;TForm1.GetColor(x,y:ShortInt);i,j:ShortInt;i:=0 To 7 Doj:=0 To 7 Do Int24ToInt3_8(Form2.Image1.Canvas.Pixels[i+x*8,j+y*8],i,j);TForm1.PutColor(x,y:ShortInt);i,j:ShortInt;i:=0 To 7 Doj:=0 To 7 Do Form2.Image1.Canvas.Pixels[i+x*8,j+y*8]:=RGB(TOC[i,j],TOC[i,j],TOC[i,j]);TForm1.ToCos;i,j,x,y:ShortInt;,d:Real;i:=0 To 7 Doj:=0 To 7 Do:=0;(i>0) And (j>0) Then d:=1If (i=0) And (j=0) Then d:=1/2d:=1/Sqrt(2);x:=0 To 7 Doy:=0 To 7 Do s:=s+clRGB[x,y]*Cos((2*x+1)*i*Pi/16)*Cos((2*y+1)*j*Pi/16);[i,j]:=Trunc(s*d/4);TForm1.CosTo;i,j,x,y:ShortInt;,d:Real;x:=0 To 7 Doy:=0 To 7 Do:=0;i:=0 To 7 Doj:=0 To 7 Do(i>0) And (j>0) Then d:=1If (i=0) And (j=0) Then d:=1/2d:=1/Sqrt(2);:=s+d*TOC[i,j]*Cos((2*x+1)*i*Pi/16)*Cos((2*y+1)*j*Pi/16);[x,y]:=Round(s/4);i:=0 To 7 Doj:=0 To 7 Do TOC[i,j]:=T[i,j];TForm1.TKwant;i,j:Byte;i:=0 To 7 Doj:=0 To 7 Do TKW[i,j]:=1+((1+i+j)*Form1.Quality.Value);;TForm1.ToKwant; //Квантовательi,j:Byte;i:=0 To 7 Doj:=0 To 7 Do TOC[i,j]:=Trunc(TOC[i,j]/TKW[i,j]);TForm1.KwantTo; //Деквантовательi,j:Byte;i:=0 To 7 Doj:=0 To 7 Do TOC[i,j]:=TOC[i,j]*TKW[i,j];
{***********************************************************}TForm1.TR(var x: Integer;var y: Integer;S: ShortInt);(x);(Posit);S=1 Then Zgzg[Posit]:=TOC[x,y]TOC[x,y]:=DcD[Posit];;TForm1.TD(var x: Integer;var y: Integer;S: ShortInt);(y);(Posit);S=1 Then Zgzg[Posit]:=TOC[x,y]TOC[x,y]:=DcD[Posit];;TForm1.TLD(var x: Integer;var y: Integer;S: ShortInt);(y);(x);(Posit);S=1 Then Zgzg[Posit]:=TOC[x,y]TOC[x,y]:=DcD[Posit];;TForm1.TRU(var x: Integer;var y: Integer;S: ShortInt);(x);(y);(Posit);S=1 Then Zgzg[Posit]:=TOC[x,y]TOC[x,y]:=DcD[Posit];;TForm1.Zigzag(Style: ShortInt);i,j:Integer;:=0;:=0;:=0;Style=1 Then Zgzg[Posit]:=TOC[i,j]TOC[i,j]:=DcD[Posit];(i,j,Style);(i<7) and (j>=0) doi<>0 do TLD(i,j,Style);(i,j,Style);j<>0 do TRU(i,j,Style);(i,j,Style);(i<=7) And (j<6) doj<>7 do TLD(i,j,Style);(i,j,Style);i<>7 do TRU(i,j,Style);(i,j,Style);;(i,j,Style);(i,j,Style);;TForm1.ToBinTo(Digit:SmallInt;N:ShortInt);i,k:ShortInt;: Array [0..15] of Integer;i:=0 To N-1 Do Begin k:=Digit Mod 2;[i]:=k;:=Digit Div 2;i:=N-1 DownTo 0 do BinA:=BinA+IntToStr(Nol[i]);:=RabFile+BinA;;TForm1.ToBin(Digit:SmallInt;N:ShortInt);i,k:ShortInt;:SmallInt;:='';:=Digit;:=1;:=0;p<0 Then BinA:=BinA+IntToStr(i)BinA:=BinA+IntToStr(k);:=Abs(Digit);(Digit,N-1); BinA:='';;TForm1.ChoiceAmp(Digit:SmallInt);Digit Of
,0..1:Begin ToBinTo(2,4); ToBin(Digit,2) End;
..-2,2..3:Begin ToBinTo(3,4); ToBin(Digit,3) End;
..-4,4..7:Begin ToBinTo(4,4); ToBin(Digit,4) End;
..-8,8..15:Begin ToBinTo(5,4); ToBin(Digit,5) End;
..-16,16..31:Begin ToBinTo(6,4); ToBin(Digit,6) End;
..-64,64..127:Begin ToBinTo(8,4); ToBin(Digit,8) End;
..-128,128..255:Begin ToBinTo(9,4); ToBin(Digit,9) End;
..-256,256..511:Begin ToBinTo(10,4); ToBin(Digit,10) End;
..-512,512..1024:Begin ToBinTo(11,4); ToBin(Digit,11) End;TForm1.Coding;ZeroCounter: Integer;: Integer;:='';(1);:=0;n:=0 to 63 Do Begin BinA:='';Zgzg[n]=0 Then Begin(ZeroCounter);ZeroCounter=15 Then
Begin(15,4); BinA:='';(0,4); BinA:='';:=0;
endbegin(ZeroCounter,4); BinA:='';(Zgzg[n]); BinA:='';:=0;;;ZeroCounter<>0 Then(ZeroCounter,4); BinA:='';(0,4); BinA:='';:=0;;
{***********************************************************}TForm1.BinToSym1Dec;,i: ShortInt;: String;: Array [0..3] of Integer;:=0;:=0;i:=0 To 3 Do[i]:=StrToInt(RabFile[i+prf]);(prf,4);i:=3 DownTo 0 do Begin:=Nol[i];k=1 Then Inc(Sym11,Trunc(exp((3-i)*Ln(2))));i:=0 To 3 Do[i]:=StrToInt(RabFile[i+prf]);//Read(F,k);(prf,4);i:=3 DownTo 0 do Begin:=Nol[i];k=1 Then Inc(Sym12,Trunc(exp((3-i)*Ln(2))));
//inc(prf);;TForm1.BinToSym2Dec;k,i: ShortInt;: Byte;: Array [0..15] of integer;Sym12<>0 Then:=StrToInt(RabFile[prf]);//Read(F,k);(prf);:=k;:=0;i:=0 To Sym12-2 Do[i]:=StrToInt(RabFile[i+prf]);//Read(F,k);(prf,Sym12-1);i:=Sym12-2 DownTo 0 do Begin:=Nol[i];k=1 Then Inc(Sym2,Trunc(exp((Sym12-2-i)*Ln(2))));
// Inc(prf);Mark=1 Then Sym2:=-Sym2;Sym2:=0;
// Inc(prf);;TForm1.Decoding;i:Byte;:=1;i:=0 to 191 do DcD[i]:=0;:=0;i< 64 doDec;Dec;
//DcD[i]:=Sym11;
//DcD[i+1]:=Sym12;Sym11=0 Then i:=i+1If Sym11=15 Then i:=i+Sym11i:=i+1+Sym11;[i-1]:=Sym2;;(0);;
{***********************************************************}TForm1.RabFileToLongInt;o,k,i,j,n: Integer;: String;: LongInt;: Array [1..64] of String;: Array [1..64] of Integer;i:=1 to 64 do WW[i]:='';:=0;(RabF,IntToStr(Length(RabFile)));:=Length(RabFile) Mod 24;:=Trunc(Length(RabFile)/24);o>0 Then inc(k);(RabF,IntToStr(k));j:=1 to k doi:=(24*j)-23 to 24*j doi>=length(rabfile) then ww[j]:=ww[j]+'0'[j]:=WW[j]+RabFile[i];;j:=1 to k do Begin Lon:=0;i:=1 to 24 do Nol[i]:=StrToInt(WW[j][i]);i:=24 DownTo 1 do Begin:=Nol[i];n=1 Then Inc(Lon,Trunc(exp((24-i)*Ln(2))));
// Form1.Memo1.Lines.Add(IntToStr(Lon));(RabF,IntToStr(Lon));;TForm1.LongIntToRabFile;k,i,j: Integer;: Array [0..23] of Integer;: LongInt;, Kol:Integer;,R: String;:=0; RabFile:='';(RabF,LengthRabFile);(RabF,Kol);i:=1 to 24 do Nol[i]:=0;j<Kol do begin:='';(RabF,DigitS);:=StrToInt(DigitS);i:=0 To 23 Do Begin k:=Digit Mod 2;[i]:=k;:=Digit Div 2;i:=23 DownTo 0 do BinA:=BinA+IntToStr(Nol[i]);:=R+BinA;(j);;i:=1 to LengthRabFile do:=RabFile+R[i];;
{***********************************************************}TForm1.CompressionClick(Sender: TObject);x,y,i,j: integer;:Byte;(RabF,Form1.Edit1.Text);(RabF);(RabF,PImage.biWidth);(RabF,PImage.biHeight);
//ToBinTo(PImage.biWidth,12);
//ToBinTo(PImage.biHeight,12);;
// ShowMessage('Наберитесь терпения');x:=0 To Trunc((PImage.biWidth+1)/8)-1 Doy:=0 To Trunc((PImage.biHeight+1)/8)-1 Do(x,y);;;;
// RabFileToLongInt;;;(x,y);;;(RabF);TForm1.DecompressionClick(Sender: TObject);x,y,i,k:Word;:ShortInt;,H: Integer;:='';//OpenDialog1.Filter:='Файлы для декомпресии (*.Zo)|*.Zo';OpenDialog1.Execute Then.Visible:=True;;(RabF,OpenDialog1.FileName);(RabF);
{ k:=0;i:=0 To 11 Do Begin Read(F,j); If j=1 Then Inc(k,Trunc(exp(j*ln(2)))) End;.Width:=k+6;:=0;i:=0 To 11 Do Begin Read(F,j); If j=1 Then Inc(K,Trunc(exp(j*ln(2)))) End;.Height:=k+23; }.Top:=120;.Left:=120;(RabF,W);(RabF,H);.Image1.Width:=W;.Image1.Height:=H;.Width:=W+10;.Height:=H+10;
// ShowMessage('Наберитесь терпения');x:=0 To Trunc((Form2.Image1.Width)/8)-1 Doy:=0 To Trunc((Form2.Image1.Height)/8)-1 Do;;;;(x,y);(RabF);
{procedure TForm1.SpeedButton1Click(Sender: TObject);i,j,s: Integer;,Trpr1,Trpr2,Trpr3,Trpr4: String;(RabF,'c:\Abracadabra.txt');(RabF);.Top:=0;.Left:=0;
// Form1.Memo1.Lines.Add('***TOC******');:='';:='';:=1;i:=0 To 7 doj:=0 To 7 do Begin[i,j]:=0;(s);
// If i+j=5 Then TOC[i,j]:=i+1;s<53 Then TOC[i,j]:=s;:=Trpr+' '+IntToStr(TOC[i,j]);;
{ For i:=0 To 7 doj:=0 To 7 do Begin[i,j]:=s;s<45 Then s:=s+1;:=Trpr+' '+IntToStr(TOC[i,j]);; }
{ Form1.Memo1.Lines.Add(Trpr);.Memo1.Lines.Add('***Zgzg******');;i:=0 to 63 do Trpr1:=Trpr1+' '+IntToStr(Zgzg[i]);.Memo1.Lines.Add(Trpr1);.Memo1.Lines.Add('***RabFile******'+'prf'+IntToStr(prf));.Memo1.Lines.Add(RabFile);;
{ Form1.Memo1.Lines.Add('***DcD******');;i:=0 to 63 do Trpr2:=Trpr2+' '+IntToStr(DcD[i]);.Memo1.Lines.Add(Trpr2);.Memo1.Lines.Add('***NewTOC******');i:=0 To 7 doj:=0 To 7 do:=Trpr3+' '+IntToStr(TOC[i,j]);.Memo1.Lines.Add(Trpr3);.Memo1.Lines.Add('***Длина RabFile******');.Memo1.Lines.Add(IntToStr(Length(RabFile)));
{ Form1.Memo1.Lines.Add('***RabFile в LongInt******');;
// Form1.Memo1.Lines.Add('***NewRabFile******');
// LongIntToRabFile;
// Form1.Memo1.Lines.Add(NewRabFile); }
{ CloseFile(RabF);
// Zigzag;
// for s:=0 to 63 do Form1.Memo1.Lines.Add(IntToStr(Zgzg[s]));}
{end;TForm1.SpeedButton2Click(Sender: TObject);i,j,s: Integer;,Trpr1,Trpr2,Trpr3,Trpr4: String;
{ BinA:='';:= StrToInt(Form1.LabeledEdit2.Text);(a,8);.LabeledEdit1.Text:=BinA;}
{ AssignFile(RabF,'c:\Abracadabra.txt');(RabF);;.Memo1.Lines.Add('***NewRabFile******');.Memo1.Lines.Add(RabFile);.Memo1.Lines.Add('***DcD******');;i:=0 to 63 do Trpr2:=Trpr2+' '+IntToStr(DcD[i]);.Memo1.Lines.Add(Trpr2);.Memo1.Lines.Add('***NewTOC******');i:=0 To 7 doj:=0 To 7 do:=Trpr3+' '+IntToStr(TOC[i,j]);.Memo1.Lines.Add(Trpr3);;}.Form2: TForm2= 416= 233= False= #1043#1083#1103#1085#1100' '#1085#1072' '#1084#1077#1085#1103= 304= 307= clBtnFace.Charset = DEFAULT_CHARSET.Color = clWindowText.Height = -11.Name = 'MS Sans Serif'.Style = []= False= 96= 13Image1: TImage= 64= 40= 185= 161= True