Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static bool CompressVar(string pathSrc, string pathDest)
- {
- int codeLength = 8;
- BitArray bufferLSB = new BitArray(8);
- BitArray bufferMSB = new BitArray(8);
- FileStream sourceFile = new FileStream("pathSrc", FileMode.Open, FileAccess.Read);
- using (StreamReader sr = new StreamReader(sourceFile))
- {
- FileStream destFile = new FileStream("pathDest", FileMode.OpenOrCreate, FileAccess.Write);
- using (BinaryWriter bw = new BinaryWriter(destFile))
- {
- //ako su sve 1 racunacemo kao kraj duzine i prelazimo na vecu duzinu
- var pattern = new StringBuilder();
- var newPattern = new StringBuilder();
- ushort buffer = 0;
- ushort queue = 0;
- Dictionary<string, ushort> map = new Dictionary<string, ushort>(); //nov recnik
- //populacija recnika ASCII tabelom
- for (int i = 0; i < 256; i++)
- {
- map.Add(((char)i).ToString(), (ushort)i);
- }
- int bufferSpace = 16; //glavni bafer za upis
- while (!sr.EndOfStream)
- {
- if(codeLength == 13) //da bismo ogranicili rast tablice do 12 bitova
- {
- codeLength = 8;
- map.Clear();
- for (int i = 0; i < 256; i++)
- {
- map.Add(((char)i).ToString(), (ushort)i);
- }
- }
- int readChar = sr.Read();
- newPattern = pattern.Append(readChar); //proveravamo novi pattern
- if (map.ContainsKey(newPattern.ToString()))
- {
- pattern = newPattern;
- }
- else
- {
- map.Add(newPattern.ToString(), (ushort)map.Count); //kodiramo novi pattern
- ushort code = map[pattern.ToString()];
- int pending = 16 - (ushort)(Math.Log2((double)code)+1); //koliko je dugacak trenutni kod sa kojim radimo? mozda i moze codeLenght
- if (bufferSpace >= pending) //da li imamo prostora u baferu da smestimo taj kod
- {
- buffer = (ushort)(buffer | code); //smesti ga u donje bitove
- buffer = (ushort)(buffer << bufferSpace - pending); //pomeri levo u gornje
- bufferSpace -= pending; //smanji prostor dostupan u baferu
- if (bufferSpace == 0) //msm da nece nikad da se desi ali neka ga
- {
- bw.Write(buffer);
- buffer = 0;
- bufferSpace = 16;
- }
- }
- else if (bufferSpace < pending && bufferSpace > 0) //moze da se smesti kod ali samo delimicno
- {
- int fragmentSpace = pending - bufferSpace; //odredjujemo koliki deo koda moze
- int queueSpace = codeLength - fragmentSpace; //koliki deo ne moze
- ushort mask = (ushort)(Math.Pow(2, fragmentSpace) - 1);//pravimo masku za izvlacenje ova dva dela
- queue = (ushort)(mask & code);//izvlacimo deo koji ne moze
- mask = (ushort)(~mask);//sredjujemo masku za deo koji moze
- ushort fragment = 0;
- fragment = (ushort)(mask & code);//izvlacimo deo koji moze
- fragment = (ushort)(fragment >> fragmentSpace);//pomeramo ga na zadnje bitove jer su oni dostupni u baferu
- buffer = (ushort)(buffer | fragment);//dodajemo ih u bafer
- bw.Write(buffer);//praznimo bafer u strim
- buffer = 0;
- bufferSpace = 16;
- buffer = (ushort)(buffer | queue);//dodajemo deo koji nije mogao da se smesti
- buffer = (ushort)(buffer << bufferSpace - queueSpace);//pomeramo ga na pocetak
- bufferSpace -= queueSpace;//smanjujemo prostor u baferu
- }
- else//ne bi trebalo da se desi nikad
- {
- bw.Write(buffer);
- buffer = 0;
- bufferSpace = 16;
- }
- pattern = new StringBuilder(((char)readChar).ToString()); //resetujemo pattern
- if (map.Count-1 == Math.Pow(2, codeLength)) //provera za produzenje koda
- codeLength++;
- }
- }
- }
- }
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement