реклама на сайте
подробности

 
 
> Восстановление данных переданных по радиоканалу., Кодирование файла JPEG.
_Leo_
сообщение Apr 22 2010, 14:36
Сообщение #1





Группа: Участник
Сообщений: 5
Регистрация: 23-04-09
Пользователь №: 48 123



Необходимо написать программу восстанавливающую данные - файл JPEG, переданные по беспроводному каналу.
Ограничения: использовать как можно меньше вычислительных ресурсов, при использовании избыточных кодов добавляемая информация не

должна превышать 10% от изначального объёма.
Если чуть подробнее, то полученная картинка обрабатывается (кодируется) микроконтроллером AVR32 AT32UC3 и передаётся по

беспроводному каналу NanoNet. Принимаются данные на ПК, там происходит их декодирование. Язык программирования С.

Так как повторная передача исключена, то кроме корректирующих кодов вариантов вроде нет.
Корректирующие коды выбираются исходя из наиболее вероятного типа ошибок, вот тут пробел - какой тип ошибок более характерен для

NanoNet? У него частота что и у WiFi, но модуляция другая.
Для одиночных ошибок лучше всего подходит классика - код Хемминга. Учитывая 10% ограничение минимально возможный код (63, 57).
Только работа в с файлами происходит побайтно и использование такого кода означает лишние сдвиги, создание массивов и т.д. Как вариант

код (88,80), но он избыточен и лишь чуть более удобен.
Циклические коды БЧХ или Рида-Соломона выглядят более привлекательными и вроде не сложны в реализации. У БЧХ как я понимаю можно

задавать и длину кодируемого блока и количество исправляемых ошибок. Для кода Рида-Соломона в качестве символа можно задать байт.

В общем задача с разными решениями и где оптимальный путь, пока не определил.
С благодарностью приму любой совет.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
_Leo_
сообщение May 31 2010, 14:30
Сообщение #2





Группа: Участник
Сообщений: 5
Регистрация: 23-04-09
Пользователь №: 48 123



Просмотрев несклько черно-белых JPEG файлов пожатых с хорошим качеством выяснил, что заголовок (до маркера FFDA)
находится в пределах 0,8 - 1,5%. Округлил до 2%.
Закодировал заголовок циклическим кодом (7, 4).

CODE
#include <stdio.h>
#include <stdlib.h>


#define BSIZE 512

short int coder(unsigned char);

int main(int argc, char *argv[])
{

unsigned char bufRead[BSIZE], buf2uc[2], a;
FILE *fdWrite, *fdRead;
short int numByte = 0, buf2si[2], i, ac;
int cnt = 0;

fdRead = fopen("a.dat", "rb");
if (fdRead == NULL)
{
printf ("Oshibka pri otkritii faila Read\n");
exit(1);
}
else
printf ("\nFile Read otkrit\n");

fdWrite = fopen("acode.dat","wb");
if (fdWrite == NULL)
{
printf ("Oshibka pri otkritii faila Write\n");
exit(1);
}
else
printf ("File Write otkrit\n");


do
{
fread(bufRead, sizeof(unsigned char), BSIZE, fdRead);
for (i = 0; i < (BSIZE - 1); i++)
{
if ((bufRead[i] == 0xff) && (bufRead[i+1] == 0xda))
{
numByte = cnt*(BSIZE-1) + i + 2;
break;
}
}
if (numByte == 0)
{
cnt++;
fseek(fdRead, -1, SEEK_CUR);
}
}
while (numByte == 0);

printf("\nKodirovat bait %i\n", numByte);

memcpy(buf2uc, &numByte, sizeof buf2uc);
buf2si[0] = coder(buf2uc[0]);
buf2si[1] = coder(buf2uc[1]);
fwrite(buf2si, sizeof(short int), 2, fdWrite);
fseek(fdRead, 0, SEEK_SET);
for (i = 0; i < numByte; i++)
{
fread(&a, sizeof(unsigned char), 1, fdRead);
ac = coder(a);
fwrite(&ac, sizeof(short int), 1, fdWrite);
}

fread(&a, sizeof(unsigned char), 1, fdRead);
while (!feof(fdRead))
{
fwrite(&a, sizeof(unsigned char), 1, fdWrite);
fread(&a, sizeof(unsigned char), 1, fdRead);
}


if (fclose (fdRead) == 0)
printf ("File Read zakrit\n");
else
printf ("Oshibka pri zakritii faila Read\n");

if (fclose (fdWrite) == 0)
printf ("File Write zakrit\n");
else
printf ("Oshibka pri zakritii faila Write\n");




getch();
return 0;
}

short int coder(unsigned char a)
{
unsigned char aH, aH_Code, aL, aL_Code;
short int i, Code;

/*
a - байт введённый для кодирования.
aH - полученный остаток от деления старших 4 бит.
aH_Code - значение закодированных 4 старших бит.
aL - полученный остаток от деления младших 4 бит.
aL_Code - значение закодированных 4 младших бит.
Code - 2 байтное число, в младшем байте содержится 7 битное число
полученное при кодировании младших 4 бит введеного числа.
В старшем байте - значение закодированных старших 4 бит.
*/

// складываем с маской для обнуления ненужных бит
// в aH хранится старший полубайт его сдвигаем вправо на два разряда
// чтобы коменсировать первый сдвиг влево в цикле
aH = a & 0xf0;
aH_Code = aH >> 1;
aH = aH >> 2;

// складываем с маской для обнуления ненужных бит
// в aL хранится младший полубайт его сдвигаем влево на два разряда
// (надо на три), третий сдвиг - первый сдвиг влево в цикле
aL = a & 0x0f;
aL_Code = aL << 3;
aL = a << 2;
// aH_Code и aL_Code хранят исходные полубайты
// сдвинутые на три разряда влево относительно первого
// к ним происходит присоединение остатка

for (i = 0; i < 4; i++)
{
aH = aH << 1;
if (aH & 0x40)
aH = aH ^ 0x58;

aL = aL << 1;
if (aL & 0x40)
aL = aL ^ 0x58;
}

// остаток получается сдвинутым на 3 разряда влево,
// поэтому надо сдвинуть его вправо
aH = aH >> 3;
aH_Code = aH_Code | aH;

aL = aL >> 3;
aL_Code = aL_Code | aL;

//16 битному числу Code присваеваем в старший байт aH_Code,
//а в младший байт aL_Code

Code = aH_Code;
Code = Code << 8;
Code = Code | aL_Code;

return Code;
}


После моделировал ошибку с помощью следующей программы:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char *argv[])
{

int i, P_err, indention;
unsigned char masErr[8] = {1,2,4,8,16,32,64,128}, a, err;
FILE *fdRead;
long fileSize, pos;
unsigned char fileName[100];

printf ("Vvedite imya faila: ");
scanf("%s", fileName);

printf ("Na skolko byte otstupit ot nachala faila: ");
scanf("%i", &indention);

printf ("Vvedite chislo byte na kotorie prixoditsa 1 oshibka: ");
scanf("%i", &P_err);

fdRead = fopen(fileName, "r+b");
if (fdRead == NULL)
{
printf ("Oshibka pri otkritii faila Read\n");
exit(1);
}
else
printf ("\nFile Read otkrit\n");

fseek(fdRead,0,SEEK_END);
fileSize = ftell(fdRead);
printf("\nThe size of file is %ld bytes\n", fileSize);

srand(time(NULL));

for (i = (indention + P_err - 1); i < fileSize; i = i + P_err)
{
fseek(fdRead, i - rand()%P_err, SEEK_SET);

// pos = ftell(fdRead);
// printf("Pos SEEK_SET+i %i \n", pos);

fread(&a, sizeof(unsigned char), 1, fdRead);

// pos = ftell(fdRead);
// printf("Pos SEEK_SET+i %i posle chteniya simvola %x\n", pos, a);


err = masErr[rand()%8];
a = a ^ err;
// printf("simvol %x posle ^ c %x\n", a, err);

fseek(fdRead, -1, SEEK_CUR);

// pos = ftell(fdRead);
// printf("Pos SEEK_SET+i-1 %i \n---------------------\n", pos);

fwrite(&a, sizeof(unsigned char), 1, fdRead);
}

if (fclose (fdRead) == 0)
printf ("File Read zakrit\n");
else
printf ("Oshibka pri zakritii faila Read\n");

getch();
return 0;
}



Ну и декодер исправляющий ошибки в закодированной части файла.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BSIZE 512

unsigned char decoder(short int);

int main(int argc, char *argv[])
{

unsigned char bufRead[BSIZE], buf2uc[2], a;
FILE *fdWrite, *fdRead;
long position;
short int numByte, buf2si[2], i, ac;
int cnt = 0, razn = 0;

fdRead = fopen("acode.dat", "rb");
if (fdRead == NULL)
{
printf ("Oshibka pri otkritii faila Read\n");
exit(1);
}
else
printf ("\nFile Read otkrit\n");

fdWrite = fopen("adecode.dat","wb");
if (fdWrite == NULL)
{
printf ("Oshibka pri otkritii faila Write\n");
exit(1);
}
else
printf ("File Write otkrit\n");



fread(buf2si, sizeof(short int), 2, fdRead);
buf2uc[0] = decoder(buf2si[0]);
buf2uc[1] = decoder(buf2si[1]);
memcpy(&numByte, buf2uc, sizeof buf2uc);

for (i = 0; i < numByte; i++)
{
fread(&ac, sizeof(short int), 1, fdRead);
a = decoder(ac);
fwrite(&a, sizeof(unsigned char), 1, fdWrite);
}

fread(&a, sizeof(unsigned char), 1, fdRead);
while (!feof(fdRead))
{
fwrite(&a, sizeof(unsigned char), 1, fdWrite);
fread(&a, sizeof(unsigned char), 1, fdRead);
}

if (fclose (fdRead) == 0)
printf ("File Read zakrit\n");
else
printf ("Oshibka pri zakritii faila Read\n");

if (fclose (fdWrite) == 0)
printf ("File Write zakrit\n");
else
printf ("Oshibka pri zakritii faila Write\n");


getch();
return 0;
}


unsigned char decoder(short int c)
{

unsigned char cL, cH, cH_Decode, cL_Decode, Decode;
short int i;

/*
с - 2 байтное число введённый для декодирования.
сH - полученный остаток от деления старшего байта.
сH_Decode - значение декодированных 4 старших бит.
сL - полученный остаток от деления младшего байта.
cL_Decode - значение декодированных 4 младших бит.
Deode - 1 байтное декодированное число.
*/

cL_Decode = (unsigned char)c;
c = c >> 8;
cH_Decode = (unsigned char)c;
cH = cH_Decode;
cL = cL_Decode;

for (i = 0; i < 4; i++)
{
if (cH & 0x40)
cH = cH ^ 0x58;
cH = cH << 1;

if (cL & 0x40)
cL = cL ^ 0x58;
cL = cL << 1;
}

cH = cH >> 4;
cL = cL >> 4;

switch(cH)
{
case 1:
printf ("oshibka v 1 bite\n");
cH_Decode = cH_Decode ^ 1;
break;

case 2:
printf ("oshibka v 2 bite\n");
cH_Decode = cH_Decode ^ 2;
break;

case 4:
printf ("oshibka v 3 bite\n");
cH_Decode = cH_Decode ^ 4;
break;

case 3:
printf ("oshibka v 4 bite\n");
cH_Decode = cH_Decode ^ 8;
break;

case 6:
printf ("oshibka v 5 bite\n");
cH_Decode = cH_Decode ^ 16;
break;

case 7:
printf ("oshibka v 6 bite\n");
cH_Decode = cH_Decode ^ 32;
break;

case 5:
printf ("oshibka v 7 bite\n");
cH_Decode = cH_Decode ^ 64;
break;

default:

break;
}


cH_Decode = cH_Decode & 0x78;
Decode = cH_Decode << 1;
cH_Decode = cH_Decode >> 3;

switch(cL)
{
case 1:
printf ("oshibka v 1 bite\n");
cL_Decode = cL_Decode ^ 1;
break;

case 2:
printf ("oshibka v 2 bite\n");
cL_Decode = cL_Decode ^ 2;
break;

case 4:
printf ("oshibka v 3 bite\n");
cL_Decode = cL_Decode ^ 4;
break;

case 3:
printf ("oshibka v 4 bite\n");
cL_Decode = cL_Decode ^ 8;
break;

case 6:
printf ("oshibka v 5 bite\n");
cL_Decode = cL_Decode ^ 16;
break;

case 7:
printf ("oshibka v 6 bite\n");
cL_Decode = cL_Decode ^ 32;
break;

case 5:
printf ("oshibka v 7 bite\n");
cL_Decode = cL_Decode ^ 64;
break;

default:

break;
}

cL_Decode = cL_Decode >> 3;
cL_Decode = cL_Decode & 0x0f;
Decode = Decode | cL_Decode;

return Decode;
}



Код конечно не оптимален, написан для проверки идеи.

Как результат:
При внесении нескольких ошибок в незакодированный файл, он зачастую не открывался. Видимо когда
ошибки приходились на заголовок.
При кодировании, внесении ошибок и декодировании, файл стабильно открывается, но даже несколько ошибок в данных
зачастую делают его визуально безнадёжно испорченным.

Очевидно данные тоже надо кодировать, причем как можно лучше.
Так как 2% избыточности из допустимых 10% использованно, то максимально допустимый вариант БЧХ (127, 120).

Сообщение отредактировал rezident - May 31 2010, 15:07
Причина редактирования: Оформление цитаты исходника.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 04:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.04014 секунд с 7
ELECTRONIX ©2004-2016