Witam
Robię projekt w którym wczytuję obrazek bmp, mam go skompresować algorytmem byterun wrzucić do własnego pliku a pozniej znowu z powrotem zdekompresować do pliku bmp. Zrobiłem dwie funkcje które kompresują i dekompresują obrazek, niby działają ale jednak nie. Jeżeli dam obrazek np 20/20 pixeli i w paincie dodam ciągi kolorów pozniej kilka jakie sie przeplatają itp to wszystko jest idealnie, jednak jak dam duży zwykły obrazek czegoś to się sypie np. dla obrazka niżej przesuwa go tylko. Mógł by ktoś w to zajrzeć i może dać jakieś pomysły czemu tak sie robi lub znaleźć błąd ? Ten programik napisałem na szybko żeby pokazać jak nam działa Byterun.
#include <iostream>
#include <stdlib.h>
#include <fstream>
using namespace std;
struct kolor // struktura koloru piksela BGR
{
unsigned char b;
unsigned char g;
unsigned char r;
};
unsigned int odczyt_i_zapis_naglowka(FILE* plik, FILE* w, unsigned char n[])
{
unsigned int szerokosc = 0;
unsigned int wysokosc = 0;
unsigned int bit_na_pixel = 0;
unsigned int ilosc_pixeli = 0;
unsigned int padding = 0;
unsigned int rzad = 0;
fread(n, 1, 54, plik); // czytamy naglowek
fwrite(n, 1, 54, w); //zapisujemy naglowek
szerokosc = *(unsigned int*)&n[18];
wysokosc = *(unsigned int*)&n[22];
bit_na_pixel = *(unsigned int*)&n[28];
padding = szerokosc % 4; // obliczamy padding
rzad = szerokosc * 3 + padding; // tyle bitow jest w rzedzie
ilosc_pixeli = wysokosc * rzad; // tyle zajmuja wszystkie piksele
return ilosc_pixeli;
}
void kompresja_ByteRun(FILE *wejsciowy, FILE *plik_wyjsciowy, unsigned int ip)
{
kolor *q = new kolor[ip];
fread(q, 1, ip, wejsciowy);
int k = 0;
kolor x, y;
int licznik1 = 0;
int licznik2 = 0;
char *wpis = new char[4];
char *zjebany_zapis = new char[128*3+1];
while (k < (ip/3))
{
x = q[k];
y = q[k + 1];
if (x.r == y.r && x.b == y.b && x.g == y.g) // gdy kolory sa takie same
{
if (licznik1 == 126)
{
wpis[0] = (licznik1)*(-1);
fwrite(wpis, 1, 4, plik_wyjsciowy);
licznik1 = 0;
}
if (licznik2 != 0)
{
zjebany_zapis[0] = licznik2 / 3 - 1;
fwrite(zjebany_zapis, 1, licznik2 + 1, plik_wyjsciowy);
licznik2 = 0;
}
licznik1++;
k++;
continue;
}
else // gdy mamy rozne kolory
{
if (licznik1 != 0)
{
wpis[0] = (licznik1)*(-1);
wpis[1] = x.b;
wpis[2] = x.g;
wpis[3] = x.r;
fwrite(wpis, 1, 4, plik_wyjsciowy);
licznik1 = 0;
k++;
}
else
{
zjebany_zapis[licznik2 + 1] = x.b;
zjebany_zapis[licznik2 + 2] = x.g;
zjebany_zapis[licznik2 + 3] = x.r;
licznik2 = licznik2 + 3;
if (licznik2 / 3 == 127)
{
zjebany_zapis[0] = licznik2 / 3 - 1;
fwrite(zjebany_zapis, 1, licznik2 + 1, plik_wyjsciowy);
licznik2 = 0;
}
k++;
}
}
}
//gdy konczy sie plik
if (licznik1 != 0)
{
wpis[0] = (licznik1)*(-1);
wpis[1] = x.b;
wpis[2] = x.g;
wpis[3] = x.r;
fwrite(wpis, 1, 4, plik_wyjsciowy);
}
else
{
if (licznik2 != 0)
{
licznik2 = licznik2 + 3;
zjebany_zapis[0] = licznik2 / 3 - 1;
zjebany_zapis[licznik2 - 2] = y.b;
zjebany_zapis[licznik2 - 1] = y.g;
zjebany_zapis[licznik2] = y.r;
fwrite(zjebany_zapis, 1, licznik2 + 1, plik_wyjsciowy);
}
else
{
wpis[0] = 0;
wpis[1] = y.b;
wpis[2] = y.g;
wpis[3] = y.r;
fwrite(wpis, 1, 4, plik_wyjsciowy);
}
}
}
void dekompresja_ByteRun(FILE *wejsciowy, FILE *plik_wyjsciowy)
{
char x, y, z, o; // zmienne s³u¿ace do porownywania wartosci
bool plik; // zmienna pomocnicza sprawdzajaca czy sie plik nie skonczyl
plik = fread(&x, 1, 1, wejsciowy);
while (plik == true)
{
if (x >= 0) // gdy mamy rozne kolory
{
for (int i = 1; i <= x * 3 + 3; i++)
{
fread(&y, 1, 1, wejsciowy);
fwrite(&y, 1, 1, plik_wyjsciowy);
}
plik = fread(&x, 1, 1, wejsciowy);
continue;
}
else // gdy mamy takie same kolory
{
fread(&z, 1, 1, wejsciowy);
fread(&o, 1, 1, wejsciowy);
fread(&y, 1, 1, wejsciowy);
for (int i = 1; i <= (-(x)+1); i++)
{
fwrite(&z, 1, 1, plik_wyjsciowy);
fwrite(&o, 1, 1, plik_wyjsciowy);
fwrite(&y, 1, 1, plik_wyjsciowy);
}
plik = fread(&x, 1, 1, wejsciowy);
}
}
}
int main()
{
FILE *plik;
FILE *plik_wyjsciowy;
int liczba;
char* nazwa = new char;
char* nazwa1 = new char;
unsigned char naglowek[54];
unsigned int ilosc_pikseli = 0;
cout << "Wpisz nazwe pliku wejsciowego:" << endl;
cin >> nazwa;
cout << endl;
cout << "Wpisz nazwe pliku wyjsciowego:" << endl;
cin >> nazwa1;
cout << endl;
cout << "Wybierz co chcesz zrobic ( 1-kompresja , 2- dekompresja): ";
cin >> liczba;
plik = fopen(nazwa, "rb");
if (plik == NULL)
{
cout << "Blad otwarcia pliku wejsciowego!" << endl;
system("PAUSE");
exit(0);
}
plik_wyjsciowy = fopen(nazwa1, "wb");
if (plik_wyjsciowy == NULL)
{
cout << "Blad otwarcia pliku wyjsciowego!" << endl;
system("PAUSE");
exit(0);
}
switch (liczba)
{
case 1:
cout << "Kompresja Byterun" << endl;
ilosc_pikseli = odczyt_i_zapis_naglowka(plik, plik_wyjsciowy, naglowek);
kompresja_ByteRun(plik, plik_wyjsciowy, ilosc_pikseli);
break;
case 2:
cout << "Dekompresja Byterun" << endl;
ilosc_pikseli = odczyt_i_zapis_naglowka(plik, plik_wyjsciowy, naglowek);
dekompresja_ByteRun(plik, plik_wyjsciowy);
break;
}
system("PAUSE");
}