Fakt, napisali jakiś dekompresor i udostępnili źródła... Nieco przekombinowali miejscami i jakiś dziwny fix dla ujemnych zrobili ;) (dorzucenie 0x20 zer przed oknem). Tak samo wielka kombinacja alpejska poboczem drogi z counterem i offsetem dla lzss u nich, podczas gdy jest to proste jak budowa cepa ;).Ucieszą się. :P Nie wiem, czy to może o to chodzić, ale po sprawdzeniu źródeł widzę, że typy kompresji to RLE, LZSS i unknown (no chyba, że to przejęzyczenie, oni tak potrafią :)).
Ich dekompresor:
Kod: Zaznacz cały
// O "decoder[i]" serve para utiliar os bytes usados quando for encontrado um flag LZ
// sendo assim o "decoder [0] = primeiro byte" "decoder[1] = segundo byte" e assim por diante
////////////////////////////////////////
for(x = 0; x <= size_dec ; x++ ) // Isso zera todos os "decoder[]" para preparar para o processo
{
decoder[x] = 0; //printf("decoder[%02d] = %02X\n",x,decoder[x]);
}
////////////////////////////////////////
for( x = 0 ; x <= size_dec ;) // Agora começa a bagaça
{
//////////////////////////////
// Inicialmente ele cria 0x20 de zeros nescessários no arquivo temporário
if (x == 0)
{
byte = 0;
while(x < 0x20)
{
fwrite(&byte,1,1,dec); decoder[x] = 0; x++;
}
}
//////////////////////////////
fread(&flag,1,1,arq); // Leitura de um FLAG
// Se o flag for menor que 0x7E indica quantos bytes RAW deve pular para o próximo flag
// Se for maior que 0x7E é um FLAG indicando compressăo
// Sendo 0x7E repetiçăo de bytes e maior de 0x80 compressăo LZ
fprintf(log,"\nFLAG = %02X",flag); // LOG indicando um flag
if(flag >=0x7E) // LOG indicando um flag se é compressăo ou năo é
fprintf(log," de compressăo\n",flag);
else
fprintf(log," de de salto até o próximo flag\n",flag);
//getch();
if(flag == 0x00) goto END; // Se achar FLAG = 0x00 entăo termina o processo
// Caso encontre um FLAG indicando compressăo
if(flag >= 0x7E)
{
fprintf(log,"Dados comprimidos: "); // LOG indicando quais dados foram descomprimidos
/////////////////
// RLE decode
// Repetiçăo de bytes
if (flag == 0x7E)
{
unsigned int RLE = 0;
fread(&RLE,1,1,arq); RLE += 4; // Verifica quantos bytes serăo repetidos...
fread(&byte,1,1,arq); // ...e qual byte será repetido
for( y=0 ; y < RLE; y++) // Inseri os bytes repetidos
{
fwrite(&byte,1,1,dec); decoder[x] = byte; fprintf(log,"%04X",byte); x++;
}
}
/////////////////
// Ainda desconhecido e provavelmente năo tem, năo custa nada colocar caso ocorra.
if (flag == 0x7F) // ???
{
printf("\nCompressao desconhecida encontrada: %02X\n",flag);
getch();
}
/////////////////
// LZ decode
if (flag >= 0x80)
{
int LZflag = 0;
unsigned long int OFFSET = 0;
int OFFSET_CENT = 0;
fread(&OFFSET,1,1,arq); // Lę o posicionamento de onde o dado comprimido está
LZflag = flag - 0x80;
LZbyte = 3;
// O Flag é dividido em octal, entăo este processo verifica quantos bytes
// e quanto adiciona no deslocamento
OFFSET_CENT = 0;
for( y=0, i=1 ; y < LZflag; y++)
{
if(i == 0x8)
{
OFFSET_CENT = 0; LZbyte += 1 ; i=0; // A cada octal é mais um byte para a descompressăo
}
else
OFFSET_CENT += 0x100;
i++;
}
// Adiciona 0xX00 ao deslocamento do LZ
OFFSET += OFFSET_CENT;
// Aqui é repetiçăo de byte LZ sendo assim repetindo uam sequęncia de bytes em outra área (BASE Lempel-Ziv)
for( y=0 ; y < LZbyte ; y++)
{
decoder[x] = decoder[x - (OFFSET+1)]; fprintf(log,"%02X ",decoder [x]);
fwrite(&decoder[x],1,1,dec); x++;
}
}
}
//////////////////////////////
// Caso seja um flag de salto ele gravará o tamanho do salto em arquivos sem compressăo
else
{
fprintf(log,"Dados RAW: "); // LOG
for(y = 0; y < flag ; y++)
{
// Praticamente é um copia e cola de um arquivo pro outro
decoder[x] = 0; fread(&decoder[x],1,1,arq); fwrite(&decoder[x],1,1,dec); fprintf(log,"%02X ",decoder[x]); x++;
}
fprintf(log,"\n"); // LOG
}
}
///////////////////////////////////////
END: // Caso o arquivo termine no LOOP eel pula para o processo final que é este
Kod: Zaznacz cały
void ffxDecompress(unsigned char *bufferin, unsigned char *bufferout, unsigned int insize, unsigned int outsize)
{
unsigned char* src = bufferin;
unsigned char* dst = bufferout;
while (src[0] != 0 && (unsigned int)(src-bufferin) < insize && (unsigned int)(dst-bufferout) < outsize)
{
if (src[0] < 0x7e)
{//uncompressed
memcpy(dst, &src[1], src[0]);
dst += src[0];
src += 1 +src[0];
} else
{//compressed
if (src[0] < 0x80)
{//RLE
int tmpCnt = (((src[0] - 0x7e)<<8) | src[1])+4;//so 515 max, but it can be only 259 if 0x7e is used and 0x7f is somehow reserved
memset(dst, src[2], tmpCnt);
dst += tmpCnt;
src += 3;
} else
{//LZSS
int tmpCnt = ((src[0]-0x80)/8)+3;
int tmpOff = ((((src[0]-0x80)%8)<<8) | src[1])+1;
int i;
for (i = 0; i < tmpCnt; i++)
{
int subOff = (int)(dst-bufferout)-tmpOff+i;
if ( subOff<0 )
{
dst[i] = dst[2048 +subOff];
} else
{
dst[i] = dst[i -tmpOff];
}
}
dst += tmpCnt;
src += 2;
}
}
}
}
PS2. W załączniku poprawiona wersja 0.1a. Zmieniłem tylko delikatnie kompresor. W szczególnych przypadkach pozwoli to zaoszczędzić kilka dodatkowych bajtów (bo w ostatniej wersji z rozpędu dałem zaniżoną wartość).