Здравствуйте! Предлагаю обсудить источники лучших описаний алгоритма Хаффмана, т.к. я хочу понять как это можно реализовать на ассемблере и не могу организовать правильно структуры данных для кодирования/декодирования при сжатии данных. Помогите мне и тем кто ищет информацию по методу Хаффмана. Заранее благодарен!
MAPTbIH Не можешь закодировать что? Бинарное дерево на асме? Пожалуй IMHO это наибольшая трудность. Так как даже на С++ в Хаффмане приходится своё дерево писать, врядли устроит механизм работы например STL. Но вот и начни с создания дерева. Я его реализовывал только на C++, и конечно дерево писал сам. А вообще алгоритм интересный, и не такой простой как о нём отзываются. P.S. Пара статей у меня есть в электронном виде, но они древние и вроде всем давно известные. Есть ещё статейка про арифметическое кодирование, неплохая. Правда арифм., я не делал так как тут нужна мощьная оптимизация, и скандачка нормальную реализацию не сделаешь.
Нашел статью "Хаффман в плане минимализации программ", сложная для понимания статья да еще и на ассемблере под DOS пишет. Кто-нибудь еще знает что-нибудь наипростейшее? Выкладывайте!
Да, Booster, дерево - это жесть! Да и вообще, всё это жесть. Теория понятна, а вот практика. Ума не приложу!
Когда-то давно написал хорошую реализацию этого алгоритма на...(не пинайте)... на дельфе. Но идея одна. Моя реализация бегает быстро. Если надо - скажи, я выложу.
IceFire, выкладывай, но без exe-файла, т.к. он тяжело весит, а откимпилировать я и сам смогу! На сайте www.compression.ru хорошо объясняется теория, а вот кода на асме я не видел!
Короче, дело к ночи, видимо тут тоже все супер-ассемблерщики как и я. Поэтому наверное тему можно прикрывать. Пусть зарубежные прыщавые студенты пишут программы-архиваторы и видео-кодеки, а я лучше пойду водки попью! СССР - Рулит!
MAPTbIH Ну чего разнервничался? Люди, может, работают, может им код нада выдрать... (мой случай). Как только - так сразу.
Код (Text): const SizeOfBuf = 65536*16; SizeOfDic = 65536*16; //----For Huffman---- type SizeOfArrays = 0..SizeOfDic; PTree = ^TTree; TTree = record Str: string; Next: PTree; Left: PTree; Right: PTree; Freq: DWORD; end; Codes = record number_of_bits: byte; code: byte; end; //----For Huffman---- var Freq: array [byte] of DWORD; E1, E2: BYTE; Root, T1, T2: PTree; Tree: array [byte] of PTree; Huff_Codes: array [byte] of Codes; Huff: array [0..SizeOfBuf{*100}] of Char; // Huff_Size: Longint; // k: SizeOfArrays; Exists: boolean; Freq: array [0..255] of DWORD; buffer: array [1..SizeOfBuf] of char; //===Main Array=== function Is_Contains(const sample: char; Str: String): boolean; var i: integer; begin result:= false; For i:=1 to Length(Str) do If Str[i] = Sample then begin Result:=true; Break; end; end; //----Huffman---- For i:=0 to $FF do begin New(T1); T1^.Str:=Chr(i); T1^.Next:=nil; T1^.Left:=nil; T1^.Right:=nil; T1^.Freq:=Freq[i]; If Freq[i]=0 then Dispose(T1) else Tree[i]:=T1; end; Exists:=true; while (Exists) do begin For i:=0 to $FF do If (NOT (Tree[i]=nil)) then begin E1:=i; Break; end; For i:=0 to $FF do If (NOT (Tree[i]=nil)) then If (NOT (i=E1)) then begin E2:=i; Break; end; If Tree[E2]^.Freq < Tree[E1]^.Freq then begin i:=E1; E1:=E2; E2:=i; end; For i:=0 to $FF do If (NOT (Tree[i]=nil)) then If (Tree[i]^.Freq < Tree[E1]^.Freq) then E1:=i; For i:=0 to $FF do If (NOT (Tree[i]=nil)) then If (Tree[i]^.Freq < Tree[E2]^.Freq) AND (NOT (i=E1)) then E2:=i; New(T1); T1^.Str:=Tree[E1]^.Str+Tree[E2]^.Str; T1^.Next:=nil; T1^.Left:=Tree[E1]; T1^.Right:=Tree[E2]; T1^.Freq:=Tree[E1]^.Freq+Tree[E2]^.Freq; Tree[E1]:=T1; Tree[E2]:=nil; Exists:=false; For i:=0 to $FF do begin If NOT (Tree[i] = nil) then For j:=i+1 to $FF do If NOT (Tree[j] = nil) then begin Exists:=true; Break; end; If (Exists) then Break; end; end; i:=0; while (Tree[i]=nil) do inc(i); Root:=Tree[i]; For j:=0 to $FF do Freq[j]:=0; For i:=0 to $FF do begin T1:=Root; while NOT ((T1^.Left = nil) AND (T1^.Right = nil)) do begin T2:=T1^.Left; inc(Huff_Codes[i].number_of_bits); Huff_Codes[i].code:=Huff_Codes[i].code shl 1; If Is_Contains(Chr(i), T2^.Str) then T1:=T1^.Left else begin inc(Huff_Codes[i].code); T1:=T1^.Right; end; end; end; //=====Temp code for Huffman====== AssignFile(SrcFile,NameCrypt); Reset(SrcFile,1); BlockRead(SrcFile, Huff, FileSize(SrcFile), TransBytes); Huff_Size:=0; For i:=0 to TransBytes do Huff_Size:=Huff_Size+Huff_Codes[Ord(buffer[i])].number_of_bits; Huff_Size:=Huff_Size div 8; Application.MessageBox(PChar('Предполагаемый размер по Хаффману: '+IntToStr(Huff_Size)),PChar('Коэффициент сжатия по Хаффману'), MB_OK); // //=====End temp code for Huffman===== //----Huffman---- Алгоритм не дописан и расчитан на работу с ОДНИМ символом. Надо еще сделать непосредственную замену символов битовыми последовательностями. Чуть-чуть подумай - и все напишешь, там не сложно. Будут вопросы - говори. З.Ы. Водка мозгов не прибавляет....
У меня методичка есть, 50 листов, специально для студентов написана, сам по ней реализовывал. Примеры на С++.
А кто из вас знает ответ на вопрос: "Как, зная длину всех битовых цепочек, записать их одна за другой?"
MAPTbIH Так тебя интересует как создать дерево имея битовые цепочки? Да это небольшой подводный камень. Надо будет посмотреть как я делал, а то забыл уже -).
MAPTbIH Вот так и записать. Вывалить подряд и молча в файл и всё. Формулировка такая, что непонятно о чём вопрос.
Proteus Он наверно имел ввиду как построить дерево, исходя из того, что просчитаны все битовые цепочки. Проблема в том что они разной длины. Просто когда я делал алгоритм дерева, децел пришлось подумать над этим, вот и решил что вопрос об этом, может я и неверно понял. А создать дерево для 8 бит можно так: создаёшь 256 массивов, каждый размерностью 256. Записываешь в них цепочки. Потом сортирушь всё это дело, так чтобы у тебя первые элементы массивов шли 0, 0, 0...1, 1, затем сортировка по следующим элементам массивов в подчастях 0 и 1. И потом остаётся только перенести всё это в дерево.
Проблему с записью и чтением битовых цепочек я уже решил, спасибо. Уже даже написал весь алгоритм, сжимаю NOTEPAD.EXE, весом в 69 Кбайт, а в итоге получаю сжатый фал размером в 53 Кбайт. Вот это сжатие! Плоховат немного алгоритм-то! Буду изучать арифметическое сжатие! А вообще какой алгоритм подходит для сжатия кодовой секции exe-фалов? Ето мне для вируса надо!