Nadesłany przez Tomasz Lubiński, 16 czerwca 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
RLE.java:
// Kompresja RLE (Run Length Encoding)
// www.algorytm.org
// (c) 2007 by Tomasz Lubinski
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class RLE {
/* kompresja RLE */
static void compress(FileInputStream in, FileOutputStream out) throws IOException
{
byte cur[] = new byte[1];
byte prev[] = new byte[1];
byte tmp[] = new byte[1];
char cnt = 0;
int cont;
cont = in.read(cur, 0, 1);
prev[0] = (byte) ~cur[0];
while (cont == 1)
{
if (prev[0] != cur[0])
{
if (cnt == 0)
{
/* znaki obok siebie rozne wrzuc do pliku wyjsciowego */
out.write(cur, 0, 1);
}
else
{
/* skonczyla sie sekwencja powtarzajcych sie znakow */
cnt--;
out.write(prev, 0, 1);
tmp[0] = (byte) cnt;
out.write(tmp, 0, 1);
out.write(cur, 0, 1);
cnt = 0;
}
}
else
{
/* liczbe powtarzajacych sie znakow zapisujemy na jednym bajcie
wypisz sekwencje jezeli ma ona maksymalna dlugosc */
if (cnt == 255)
{
out.write(prev, 0, 1);
tmp[0] = (byte) cnt;
out.write(tmp, 0, 1);
cnt = 0;
cont = in.read(cur, 0, 1);
prev[0] = (byte) ~cur[0];
continue;
}
else
{
/* licz powtarzajace sie znaki */
cnt++;
}
}
/* odczytaj kolejny znak z pliku wejsciowego */
cont = in.read(tmp, 0, 1);
if (cont == 1)
{
prev[0] = cur[0];
cur[0] = tmp[0];
}
}
/* jezeli plik konczy sie sekwencja wypisz ja */
if (prev[0] == cur[0])
{
cnt--;
out.write(prev, 0, 1);
tmp[0] = (byte) cnt;
out.write(tmp, 0, 1);
}
}
/* dekompresja RLE */
static void decompress(FileInputStream in, FileOutputStream out) throws IOException
{
byte cur[] = new byte[1];
byte prev[] = new byte[1];
byte cnt[] = new byte[1];
int cont, i;
cont = in.read(cur, 0, 1);
prev[0] = (byte) ~cur[0];
while (cont == 1)
{
if (prev[0] != cur[0])
{
/* znaki obok siebie rozne wrzuc do pliku wyjsciowego */
out.write(cur, 0, 1);
prev[0] = cur[0];
/* odczytaj kolejny znak */
cont = in.read(cur, 0, 1);
}
else
{
/* znaki obok siebie sa rowne - mamy sekwencje */
/* odczytaj dlugosc sekwencji i wrzuc ja do pliku wyjsciowego */
cont = in.read(cnt, 0, 1);
for (i=0; i<=(char)(cnt[0]&0xFF); i++)
{
out.write(cur, 0, 1);
}
/* odczytaj kolejny znak */
cont = in.read(cur, 0, 1);
prev[0] = (byte) ~cur[0];
}
}
}
/**
* @param args
* @throws IOException
* @throws
*/
public static void main(String[] args) throws IOException {
int x;
String inPath;
String outPath;
File in, out;
System.out.println("1 - kompresja");
System.out.println("2 - dekompresja");
x = Console.readInt("");
System.out.println("Plik wejsciowy:");
inPath = Console.readString();
System.out.println("Plik wyjsciowy:");
outPath = Console.readString();
in = new File(inPath);
out = new File(outPath);
if (x == 1)
compress(new FileInputStream(in), new FileOutputStream(out));
else
decompress(new FileInputStream(in), new FileOutputStream(out));
}
}

