Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблемы с реализацией Rle сжатия!!!!

279
20 июля 2005 года
bave
456 / / 07.03.2004
У меня возникла проблема с реализацией алгоритма сжатия RLE.
Сначала немного поясню сам алгоритм:
Допусти мы имееем последовательность: AAAAAAAAAbbbb3EFF
При сжатиии RLE повторяющиеся символы записываютя следующим образом:
в первый байт число повторений, в следующий байт само повторяющееся значение,
т. е. приведённая выше последовательность в сжатом виде будет следующей: 9A4b131E2F.

Так вот как я это реализую:
Я использую С++'овский инлайн ассемблер:

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

void TGAPacker:: compress(void *pBuffer, unsigned int cnt)
{
__asm
{
mov ecx,cnt
mov ebx,pBuffer
mov edx,ebx
label:
xor eax,eax
mov al,1
mov ah,[ebx]
equel:
mov dl,[ebx+1]
cmp ah,dl
jne n_equel
add ebx,1
add al,1
mov ah,[ebx]
dec ecx
jz exit_proc
jmp equel
n_equel:
dec ecx
add ebx,1
mov BYTE ptr [edx],al //ГЛЮЧИТ!!!!!!!
mov BYTE ptr [edx+1],ah //ГЛЮЧИТ!!!!!
add edx,1
jnz label
exit_proc:
}
}

Компилятор ошибок не находит, но при выполнении сжатия возникает ошибка - мол, память не может быть
прочитана.
Я в коментариях показал какие строки вызывают ошибки, но почему я понять не могу, кто - нить
может подсказать чё я не так делаю??????????????
279
21 июля 2005 года
bave
456 / / 07.03.2004
Нашёл я ошибку (по невнимательности - использовал
dl - для временно храния сравниваемого байта и
тут же edx для храния адреса куда он будет записываться), но теперь возникла другая
проблема - я всё исправил, но проблема возникает,
если пытаюсь работать с областью памяти больше чем
16кб - ПОЧЕМУ!!!!!
Вот последний исправленный вариант:

unsigned long TGAPacker:: compress(void *pBuffer, unsigned long cnt, UINT uCmp)
{
unsigned int ms;
if(uCmp == 0) return cnt;
__asm
{
mov ecx,cnt
mov ebx,pBuffer
mov edi,ebx
xor esi,esi
label:
xor eax,eax
mov al,1
mov ah,[ebx]
add esi,2
equel:
mov dl,[ebx+1]
cmp ah,dl
jne n_equel
add ebx,1
add al,1
mov ah,[ebx]
dec ecx
jz exit_proc
jmp equel
n_equel:
dec ecx
add ebx,1
mov BYTE ptr [edi],al
mov BYTE ptr [edi+1],ah
add edi,1
jnz label
exit_proc:
mov ms,esi
}
return ms;
}

И ещё проблем этот RLE алгоритм даже кода не глючит, всё равно хреново сжимает - на пару
кб всего растровые файлы жмёт, где нарыть
теорию по LWZ????????????, лиюо уже готовые
исходники с ходошим обяснениям как их использовать, У меня вот zlib есть исходники -
но в них чёрт ногу сломит, если ктото может,
помоч c zlib тоже буду благодарен.
3.8K
21 июля 2005 года
Supervisor
158 / / 29.05.2005
Оффтоп, конечно, но всё же позволю себе небольшой комментарий.

"Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство." F. Brooks
279
21 июля 2005 года
bave
456 / / 07.03.2004
Цитата:
Originally posted by Supervisor
Оффтоп, конечно, но всё же позволю себе небольшой комментарий.

"Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство." F. Brooks


Ну так давай найди.
(стоит добавить, что я не программист, но программировть приходится потому, что больше некому, если бы кто - то всё за меня делал....
Думашь я от хорошей жизни парюсь?)

292
22 июля 2005 года
Matush
726 / / 14.01.2004
Могу посоветовать только на счет идеи реализации упаковки, поскольку часто сталкивался с написанием архиваторов.
На счет RLE, то чтобы повысить его пригодность (все таки он в основном файлы большими делает чем были до запаковки) надо добавить в нем такую фичу как пропускать n символов из запаковываемого файла.
Вот что я имею ввиду:
Запись в исходный файл происходит так. 1-й байт это число повторений/пропусков. Если этот байт - число, до 128, значит следующий за ним байт надо повторить столько раз. Если он >127, значит следующие n-127 байт надо переписать без изменения.
Таким способом строка типа AAAAAAAABVGDHYRWE запакуется в 12 байт.
На счет LZW, то в нете есть много описалов. Если очень надо могу подкинуть свою реализацию LZW на С++ (пакует довольно неплохо).
279
22 июля 2005 года
bave
456 / / 07.03.2004
Matush - ты очень очень благое дело сделаешь
если пришлёшь следущее:
Запоковщик то у меня свой - мне нужны только
две функции (сжатия и расжатия):
Я имею ввиду вот что:
считал допустим я файлл в память,
и он храниться в памяти на которую указывает
pPtr и занимает там число байт равное fSize.
т. е. функция сжатия:
unsigned long compress(byte *pPtr,unsigned long fSize);
pPtr - после выполнеия должен указывать
на область памяти, где уже лежит сжатая последовательность байт, и функция возвращаять
чило байт сжатого файла.
Ну а функция декомпрессии наоборот.
unsigned long decompress(byte *pPtr,unsigned long fPresSize);
т. е. получает указатель на сжатый и число
байт.
возврашает:
указатель на несжатый и число байт несжатого.
---------------------------------------------
Может быть у тебя в архиваторе так и сделано.
292
25 июля 2005 года
Matush
726 / / 14.01.2004
Цитата:
Originally posted by bave
Может быть у тебя в архиваторе так и сделано.


У меня сделан класс в котором два метода пак и анпак.
вот как выглядит пак:

int MCompressor::Compress(void* lpData, int nDataLen, void** lpResData, int* nResDataLen, int* nCompressionAlgorythm)
lpData - указатель на память с данными
nDataLen - длина этого участка памяти
lpResData - указатель на память в которую будет писаться результат (выделяет класс архиватора)
nResDataLen - возвращаемый размер запакованых даных
nCompressionAlgorythm - алгоритм упаковки

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

Я оставлю в нем LZW и RLE.
Еще нюанс - в существующей версии файл пакуется разными методами, потом смотрится какой был лучше и пакуется им. Понимаю что это неефективно но для той задачи что я решал файлы запаковывались один раз, все последующие разы они только разпаковывались.
Вобщем исходную версию сделаю более оптимизированную.
Я постараюсь сегодня его привести до ума и тогда завтра выложу

279
25 июля 2005 года
bave
456 / / 07.03.2004
Ок, спасибо.
Мой упаковщик тоже для ряда определённых фарматов
сделан (остальные если в упаковываемой папке
попадаются - он их предусмотрительно игнорирует).
У меня сжиматься должны восновном - TGA,
и некотрые другие спецефические форматы.
292
26 июля 2005 года
Matush
726 / / 14.01.2004
Вчера приехал старый друг, потому я был очень пьян, сегодня отхожу. Завтра верняк прогу закину
292
09 августа 2005 года
Matush
726 / / 14.01.2004
не прошло и пол года :)

думаю по примеру будет все ясно, если что пиши.
279
11 августа 2005 года
bave
456 / / 07.03.2004
I've got it.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог