Модуль содержит классы, реализующие кодирование и декодирование в отдельном потоке (thread). Эти классы используются тестовой программой для того, чтобы визуализировать результаты работы в реальном времени, а также для предоставления возможности пользователю отменить операции кодирования и декодирования.
unit CodeThreads;
Interface
Uses
SysUtils, Code, Forms, Classes, Windows;
Const
DEF_ONPROGRESS_INTERVAL = 500;
{ интервал в миллисекундах между событиями OnProgress. Потоки (thread)
генерируют события OnProgress для того чтобы основная программа
смогла показать пользователю текущее состояние работы потока }
Type
TProgressEvent = procedure (Sender: TObject;
BitsProcessed: Int64) of object;
{ Описание обработчика события OnProgress.
Sender – объект, который сгенерировал событие OnProgress
BitsProcessed - число обработанных бит }
TDecodeCodeCreateEvent = procedure (Sender: TObject;
ACode: TCode) of object;
{ Описание обработчика события OnDecodeCodeCreate.
Данное событие генерируется после того, как поток (thread) создаст
код при декодировании. Это позволяет программе получить сведения о
|
|
коде, которым были кодированы исходные данные }
{ TCustomCodecThread
Класс для кодирования и декодирования потоков с возможностью
обработки прогресса и отмены операции }
TCustomCodecThread = class (TThread)
Private
FCode: TCode;
{ код, которым производится кодирование }
FDecodeCode: TCode;
{ код использующийся для декодирования, создается автоматически на
основе информации во входном потоке }
FOutStream: TStream;
{ поток вывода}
FInStream: TStream;
{ поток ввода}
FWorking: Boolean;
{ Признак того, что поток (thread) в данный момент работает }
FInterval: Cardinal;
{ Интервал в миллисекундах, через который генерируются события
OnProgress }
FBitsProcessed: Int64;
{ Число обработанных бит (при кодировании и декодировании) }
FException: Exception;
{ Хранит объект исключительной ситуации на время работы
обработчика события OnException }
FEncodeMode: Boolean;
{ Задает режим работы потока (thread).
Если истина, то кодирование. Если ложь - декодирование }
FOnException: TExceptionEvent;
{ Указатель на обработчик события OnException.
Данное событие генерируется при возникновении исключительной
ситуации во время процесса кодирования и декодирования }
FOnProgress: TProgressEvent;
{ Указатель на обработчик события OnProgress.
Событие периодически генерируется во время процессов
кодирования и декодирования }
FOnDecodeCodeCreate: TDecodeCodeCreateEvent;
{ Указатель на обработчик события OnDecodeCodeCreate }
{ Set методы для свойств класса. Большинство из
них игнорируют новые значения для свойств класса
если FWorking = True }
procedure SetCode(const Value: TCode);
procedure SetInterval(const Value: Cardinal);
procedure SetInStream(const Value: TStream);
procedure SetOutStream(const Value: TStream);
procedure SetEncodeMode(const Value: Boolean);
{ Методы вызова обработчиков событий }
|
|
procedure CallOnDecodeCodeCreate;
procedure CallOnProgress;
procedure ExceptionHandler;
Protected
{ Проверка параметров перед началом кодирования
В случае обнаружения ошибки - исключение }
procedure EncodeCheck; virtual;
{ Проверка параметров перед декодированием
В случае ошибки - исключение }
procedure DecodeCheck; virtual;
{ Запись заголовочных данных (THeader и информация о коде) в
выходной поток }
procedure WriteHeaders; virtual;
{ Чтение заголовочных данных из входного потока }
procedure ReadHeaders; virtual;
{ Кодирование входного потока и его запись в выходной поток.
Наследники могут перекрывать этот метод, если хотят изменить
процесс кодирования }
procedure EncodeProc; virtual;
{ Декодирование входного потока и его запись в выходной поток.
Наследники могут перекрывать этот метод, если хотят изменить
процесс декодирования }
procedure DecodeProc; virtual;
{ Свойства класса }
property Code: TCode read FCode write SetCode;
property DecodeCode: TCode read FDecodeCode;
{ Код использующийся при декодировании.
DecodeCode <> nil только во время процесса декодирования.
После окончания декодирования снова становится равным nil }
property EncodeMode: Boolean read FEncodeMode write SetEncodeMode;
property InStream: TStream read FInStream write SetInStream;
property OutStream: TStream read FOutStream write SetOutStream;
property Working: Boolean read FWorking;
{ События }
property OnDecodeCodeCreate: TDecodeCodeCreateEvent
read FOnDecodeCodeCreate write FOnDecodeCodeCreate;
property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
property Interval: Cardinal read FInterval write SetInterval;
property OnException: TExceptionEvent read FOnException
write FOnException;
Public
constructor Create(AEncodeMode: Boolean = True);
procedure Execute; override;
{ Метод реализует работу потока (thread) }
end; { TCustomCodecThread }
{ TCodecThread
Наследник TCustomCodecThread. Просто публикует свойства
класса TCustomCodecThread }
TCodecThread = class (TCustomCodecThread)
Public
property Code;
property EncodeMode;
property InStream;
property Interval;
property OutStream;
property OnDecodeCodeCreate;
property OnProgress;
property OnException;
end; { TEncodeThread }
{ TFileEncodeThread
Наследник TCustomCodecThread, надстройка. Позволяет сделать
кодирование и декодирование файлов проще.
Нужно указать имена исходного и целевого файлов, автоматически
будут созданы соответствующие потоки }
TFileCodecThread = class (TCustomCodecThread)
Private
FInputFileName: String;
{ Имя исходного файла }
FOutputFileName: String;
{ Имя целевого файла }
{ Set методы свойств класса }
procedure SetInputFileName(const Value: String);
procedure SetOutputFileName(const Value: String);
Public
destructor Destroy; override;
{ Свойства класса }
property InputFileName: String read FInputFileName
write SetInputFileName;
property OutputFileName: String read FOutputFileName
write SetOutputFileName;
{ Публикация свойств унаследованных от TCustomCodecThread }
property EncodeMode;
property Code;
property Interval;
property OnDecodeCodeCreate;
property OnProgress;
property OnException;
end; { TFileEncodeThread }
Модуль «RM.pas»
Содержит реализацию кода Рида-Маллера.
unit RM;
Interface
Uses
BitsUtils, Code, MathUtils, Windows, SysUtils, Classes;
{ Параметры кода Рида-Маллера по умолчанию }
Const
DEF_RM_M = 5;
DEF_RM_R = 2;
Type
ERMCode = class (ECode);
TRMCode = class (TCode)
Private
{ Параметры кода Рида-Маллера }
FM: Integer;
FR: Integer;
{ Новые параметры кода Рида-Маллера. Эти поля используются
set-методами свойств R, M. Когда оба поля принимают ненулевые
значения, проверяется допустимость этих параметров. Если
они допустимы, то происходит создание новой порождающей матрицы
и т.п. }
FNewM: Integer;
FNewR: Integer;
FGkRows: array of Integer;
{ Массив числа строк в минорах G_k порождающей матрицы.
Используется при декодировании для увеличения производительности }
procedure FreeCode;
{ Освобождает память занятую порождающей матрицей, характеристическими
векторами и FGkRows }
procedure FreeCharacterVectors;
{ Освобождает память занятую характеристическими векторами }
procedure FreeGeneratorMatrix;
{ Освобождает память занятую порождающей матрицей }
Protected
FK: Integer;
{ Размер информационного свойства }
FN: Integer;
{ Размер кодового слова }
FG: array of TWord;
{ Порождающая матрица }
FCharacterVectors: array of array of TWord;
{ Характеристические векторы для строк порождающей матрицы }
|
|
procedure BuildGeneratorMatrix;
{ Строит порождающую матрицу }
procedure BuildCharacterVectors;
{ Строит характеристические векторы для строк порождающей матрицы.
Используется для ускорения процесса декодирования }
procedure GenerateCode;
{ Проверяет допустимость FNewR и FNewM. Если все в порядке,
вызывает FreeCode, а затем BuildGeneratorMatrix и
BuildCharacterVectors.
FNewR, FNewM сбрасываются в 0 }
procedure FillE(var E: array of Integer; Monomial: array of Integer);
{ Заполняет множество E, состоящее из индексов переменных от 1 до M
не входящих в моном Monomial. Используется при генерации
характеристических векторов.
Пример: M = 3. Monomial = [1]. Тогда E = [2, 3] }
procedure NextIndexes(var Indexes: array of Integer);
{ Генерирует всевозможные перестановки на M элементах длины
Length(Indexes).
Используется при генерации строк порождающей матрицы }
{ Set-методы свойств }
procedure SetM(Value: Integer);
procedure SetR(Value: Integer);
{ Перекрытые методы, унаследованные от TCode }
function GetK: Integer; override;
function GetN: Integer; override;
function GetFullName: String; override;
class function GetName: String; override;
Public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ Перекрытые методы, унаследованные от TCode }
procedure Encode(Word: TWord; CodeWord: TCodeWord); override;
procedure Decode(RecievedWord: TCodeWord; Word: TWord); override;
{ Свойства класса }
property K: Integer read GetK;
property N: Integer read GetN;
Published
{ Published свойства автоматически сохраняются при записи класса в
поток, и восстанавливаются при создании класса из потока.
При декодировании это позволяет создать код Рида-Маллера
с теми параметрами, которые использовались при кодировании }
property M: Integer read FM write SetM default DEF_RM_M;
property R: Integer read FR write SetR default DEF_RM_R;
end; { TRMCode }
Модуль «BCH.pas»
Содержит реализацию кода БЧХ(5, 15, 7).
unit BCH;
Interface
Uses
SysUtils, Code, BitsUtils, Windows, Math, Classes;
Const
{ Параметры кода }
BCH_K = 5;
BCH_N = 15;
BCH_D = 7;
{ Число слов длины 15 и кодовых слов }
BCH_WORDS_COUNT = 32768; { 2^15 }
BCH_CODEWORDS_COUNT = 32; { 2^5 }
{ Порождающий многочлен для БЧХ(5, 15, 7):
x^10 + x^8 + x^5 + x^4 + x^2 + x + 1 }
{ Порождающая матрица }
BCH_GEN: array [0..BCH_K-1, 0..BCH_N-1] of TBit =
((1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0),
(0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0),
(0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0),
|
|
(0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0),
(0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1)
);
Type
{ Класс исключительной ситуации }
EBCHCode = class (ECode);
{ БЧХ код (5, 15, 7)
Используется табличное кодирование и декодирование }
TBCHCode = class (TCode)
Protected
{ Параметры кода }
FK: Integer;
FN: Integer;
{ Таблица декодирования }
FDecodeTable: array [0..BCH_WORDS_COUNT - 1] of Byte;
{ Таблица кодирования }
FEncodeTable: array [0..BCH_CODEWORDS_COUNT - 1] of Word;
{ Построение таблицы декодирования.
Cлова разбиваются на смежные классы. В каждом
смежном классе выбирается лидер и заполняется таблица декодирования }
procedure BuildDecodeTable;
{ Построение таблицы кодирования }
procedure BuildEncodeTable;
{ Перекрытые методы, унаследованные от TCode }
function GetD: Integer; override;
function GetK: Integer; override;
function GetN: Integer; override;
function GetFullName: String; override;
class function GetName: String; override;
Public
constructor Create(AOwner: TComponent); override;
constructor CreateNew;
{ Кодирование
Информационное слово рассматривается как индекс (0..31).
Кодовое слово получается копированием содержимого таблицы кодирования,
находящегося по указанному индексу }
procedure Encode(Word: TWord; CodeWord: TCodeWord); override;
{ Декодирование
Полученное слово рассматривается как индекс (0..32767}.
Информационного слово получается копированием содержимого таблицы
декодирования, находящегося по указанному индексу }
procedure Decode(RecievedWord: TCodeWord; Word: TWord); override;
{ Свойства унаследованные от TCode }
property K: Integer read GetK;
property N: Integer read GetN;
end; { TBCHCode }
Прочие модули
· MainFrm.pas – cодержит класс главного окна программы Magic Code.
· CodeWordFrm.pas – содержит класс окна, в котором можно вводить информационное слово и в ответ получать кодовое слово.
· CodecFrm.pas – класс окна визуализации процессов кодирования и декодирования файлов.
· AnalisFrm.pas – класс окна анализа кода. Окно содержит результаты анализа, обновляемые в реальном времени. Его можно закрыть в любой момент, не обязательно дожидаться окончания анализа.
· ImageDemoFrm.pas – класс окна демонстрации передачи изображения по зашумленному каналу.
Заключение
В результате проделанной работы были реализованы:
1. гибкая, легко расширяемая система, основанная на принципах объектно-ориентированного программирования;
2. класс кода БЧХ(5, 15, 7);
3. класс кода Рида-Маллера с произвольными параметрами;
4. наборы классов для операций кодирования и декодирования;
Из-за стремления к универсальности и удобству использования, скорость работы невысока. Однако, имеются большие резервы для ее повышения без ущерба универсальности и удобству.
Аттестационная работа имеет хорошие перспективы для дальнейшего развития, например, интересной представляется возможность создания универсального класса для БЧХ-кодов, а также повышение производительности до качественно нового уровня. Еще более интересной является задача исследования поведения кодов в ситуациях, когда возникающие при передаче информации ошибки превышают конструктивные способности кода их исправлять. Т.е. если код по построению способен исправлять ошибки веса не больше 3-х, то как он проявит себя с ошибками веса 4 и выше?
Данная аттестационная работа может служить пособием для изучающих основы теории кодирования.
Литература
1. Robert H. Morelos-Zaragoza, «The Art of Error Correcting Coding», Wiley, 2002.
2. Ben Cooke, «Reed_Muller Error Correcting Codes».
3. William J. Gilbert, W. Keith Nicholson, «Modern algebra with applications», 2nd ed, Wiley, 2004.
4. М. Н. Аршинов, Л. Е. Садовский, «Коды и математика (рассказы о кодировании)», М.: Наука, 1983. – 144с.
5. Лидовский В. В., «Теория информации», М.:2003. – 112с.
[1] Назначение тех или иных методов можно найти в разделе «Описание модулей», а также в комментариях к исходному коду проекта Magic Coder.