небольшой вопрос по алгоритму сжатия Хоффмана

Тема в разделе "WASM.A&O", создана пользователем varnie, 13 окт 2007.

  1. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    сегодня я сделал 2 хороших дела:
    1. хорошо сдал экзамен по 'Теории кодирования'
    2. переписал сабж, и теперь все работает как часы!
     
  2. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    рано я радовался. под FreeBSD моя прога работает на ура, все сжимает и расжимает верно. но сейчас вот попробовал перенести под винду, скомпилял там (не понаобилось даже ничего менять в сорцах, не изменил ни единой строчки). протестил. файлы с латинскими буквами итд сжимает/расжимает верно. а вот с русскими буквами косяки какие-то. после расжатия где-то после ~100 верных расжатых рус. символов тупо куча букв "а" допустим следует. попробовал сжатый виндовой версией проги файл расжать первой, которая под фрибзд скомпилена -- все прекрасно расжалось, никаких косяков.
    что я недопонимаю, или что я не учел при переносе под винду?
    из хидеров я юзал только:
    Код (Text):
    1. #include <map>
    2. #include <queue>
    3. #include <string>
    4. #include <algorithm>
    ps: могу даже свои сорцы выложить, благо они небольшие, и вполне понятные и простенькие.
    господа гуру, прошу о помощи. спасибо.
     
  3. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    еще заметил, что после расжатия фришной версией моей проги файла, который был получен после сжатия исходного файла в виндовой проге, в mc при просмотре этого файла вместо рус. букв ерунда какая-то идет. но тот же gedit верно отображает эти данные, что свидетельствует о том, что виндовая прога _верно_ осуществляет сжатие в целом.
    интересно:)
     
  4. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    //deleted
     
  5. Proteus

    Proteus Member

    Публикаций:
    0
    Регистрация:
    19 июн 2004
    Сообщения:
    344
    Адрес:
    Russia
    Ты сейчас говоришь про Хафман или арифметик? По описанию глюка больше похоже на второе. И для наводки какой у тебя компилятор под виндовсом и юзал ли ты где-то беззнаковые числа ?
     
  6. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Proteus
    1. про Хаффмана. сделал все как выше описал Ultrin Faern по шагам (т.е. получается, что при записи в файл сжатых данных байты содержат биты от от двух-трех символов).
    2. под виндовсом я использовал Dev-C++, т.е. g++ компилер получается.
    3. да, сначала в качестве поля у дерева для хранения значения символа использовал unsigned char, и данные с файла считывал как unsigned char, но потом все заменил на char. больше нигде unsigned values не использовал. после замены на char под виндой глюк не исчез.
     
  7. Ultrin Faern

    Ultrin Faern New Member

    Публикаций:
    0
    Регистрация:
    25 июн 2006
    Сообщения:
    170
    Вообще архиваторы в листьях дерева используют не байт а как минимум слово(16 бит). И дополнительно в дерево кодирования вводится символ EOF (конец текста) = 256 (можно и дроугое значение).
    Так как сжатие просто на основе дерева дает все равно плохие результаты, дополнительно вводятся коды для копирования подстрок определенной длины из предыдущего обработанного кода.

    Я думаю, у тебя проблемы с воодом\выводом из\в файл. Возьми все-таки почитай текст, на который я ссылку дал - посмотри как там это сделано (отдельная функция записи бита в поток, которая буферизирует биты в байт).
     
  8. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Енто в адаптированном алгоритме. Тогда еще вводится escape-символ для символа, ранее не встречавшегося.

    varnie
    IMHO, лучше unsigned использовать. Пример:
    char s;
    ...
    char code[0x100];

    code при s>0x7F что получится? Получится movsx вместо movzx...

    Запись/чтение вот здесь мне понравилось: http://oku.edu.mie-u.ac.jp/~okumura/compression/lzss.c
     
  9. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    KeSqueer,
    так я и использую изначально unsigned char. а под виндами та вышеупомянутая мной неувязочка с рус. буквами..
    Ultrin Faern,
    у меня аналогично сделано. есть какбы лента для заполнения битами, а также ее длина. при длине равной 8 я записываю байт в выходной файл. при декодировании похожий механизм использую - считываю по байту, и последовательно его биты перебираю, определяя, нуль это или один. как переберу все 8 бит, при следующем запросе считываю следующий байт. и опять его по байтам перебираю..
    все четко:)

    ps: уважаемые мастера дзена, может быть я сорцы все ж выложу? глянет может кто-нибудь. я был бы благодарен.
     
  10. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Давай
     
  11. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    added: сейчас разобрался немного - почему-то под виндой после записи таблицы с частотами один байт пропущенный получается в файле, и далее неверно считывается с сжатого файла таблица с частотами символов. допустим, вместо 32 частот считывается 16, и обнаруживается конец файла. скорее всего какой-то символ распознается как признак конца файла EOF!
     
  12. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    varnie
    Прикрепи пож. в аттаче.
     
  13. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    вот мои сорцы.
     
  14. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    проблема разрешена благодаря самоотверженной помощи KeSqueer.
    while (1) printf('спасибо, KeSqueer!\n');