j'ai adapté, pour les besoins de mon projet, une routine de décompression écrite à l'origine en C. Je pense l'avoir pas trop mal converti mais je rencontre un problème que je n'arrive pas à identifier. La décompression est correcte à 99% mais ce n'est pas un résultat acceptable, vous en conviendrez. Voici la routine d'origine hors contexte :
Code : Tout sélectionner
int crunch_quick(unsigned char *source, unsigned char *source_end,
unsigned char *destination, unsigned char *destination_end)
{
register unsigned int control = 0;
register int shift = 0;
int count, offset;
quick_local += 5; /* i have no idea why it adds 5 */
if(!no_clear_flag)
for(quick_local = count = 0; count < 256; count++)
quick_buffer[count] = 0;
while((destination < destination_end) && (source < source_end))
{
control <<= 9; /* all codes are at least 9 bits long */
if((shift += 9) > 0)
{
control += *source++ << (8 + shift);
control += *source++ << shift;
shift -= 16;
}
if(control & 16777216)
{
*destination++ = quick_buffer[quick_local++ & 255] = control >> 16;
}
else
{
control <<= 2; /* 2 extra bits for length */
if((shift += 2) > 0)
{
control += *source++ << (8 + shift);
control += *source++ << shift;
shift -= 16;
}
count = ((control >> 24) & 3) + 2;
offset = quick_local - ((control >> 16) & 255) - 1;
while((destination < destination_end) && (count--))
*destination++ = quick_buffer[quick_local++ & 255] =
quick_buffer[offset++ & 255];
}
} /* while */
if(DEBUG)printf(" ...quick %s",((source > source_end) || (destination != destination_end)) ? "bad" : "good");
return((source > source_end) || (destination != destination_end));
}
Code : Tout sélectionner
Procedure UnpackQuick(*source, *source_end, *destination, *destination_end)
Protected control.i, shift.i, count.i, offset.i
control = 0
shift = 0
quick_local + 5
If ~no_clear_flag
count = 0
quick_local = count
While count < 256
quick_buffer(count) = 0
count + 1
Wend
EndIf
While (*destination < *destination_end) And (*source < *source_end)
control << 9 ; all codes are at least 9 bits long
shift + 9
If shift > 0
control + PeekA(*source) << (8 + shift)
*source + 1
control + PeekA(*source) << shift
*source + 1
shift - 16
EndIf
If control & 16777216
quick_buffer(quick_local & 255) = control >> 16
PokeA(*destination, quick_buffer(quick_local & 255))
*destination + 1
quick_local + 1
Else
control << 2 ; 2 extra bits For length
shift + 2
If shift > 0
control + PeekA(*source) << (8 + shift)
*source + 1
control + PeekA(*source) << shift
*source + 1
shift - 16
EndIf
count = ((control >> 24) & 3) + 2
offset = quick_local - ((control >> 16) & 255) - 1
While ((*destination < *destination_end) And count)
count - 1
quick_buffer(quick_local & 255) = quick_buffer(offset & 255)
offset + 1
PokeA(*destination, quick_buffer(quick_local & 255))
quick_local + 1
*destination + 1
Wend
EndIf
Wend
EndProcedure
Code : Tout sélectionner
Global Dim Donnees.a(14)
Global no_clear_flag.i
Global Dim quick_buffer.a(256)
Donnees(0) = $17
Donnees(1) = $B0
Donnees(2) = $08
Donnees(3) = $51
Donnees(4) = $03
Donnees(5) = $84
Donnees(6) = $90
Donnees(7) = $56
Donnees(8) = $03
Donnees(9) = $00
Donnees(10) = $99
Donnees(11) = $30
Donnees(12) = $58
Donnees(13) = $56
Procedure UnpackQuick()
Protected control.i, shift.i, count.i, offset.i, compt.i
control = 0
shift = 0
compt = 0
quick_local + 5
If ~no_clear_flag
count = 0
quick_local = count
While count < 256
quick_buffer(count) = 0
count + 1
Wend
EndIf
While compt < 14
control << 9 ; all codes are at least 9 bits long
shift + 9
If shift > 0
control + Donnees(compt) << (8 + shift)
compt + 1
control + Donnees(compt) << shift
compt + 1
shift - 16
EndIf
If control & 16777216
quick_buffer(quick_local & 255) = control >> 16
Debug "Rout1 : $" + Hex(quick_buffer(quick_local & 255),#PB_Byte)
quick_local + 1
Else
control << 2 ; 2 extra bits For length
shift + 2
If shift > 0
control + Donnees(compt) << (8 + shift)
compt + 1
control + Donnees(compt) << shift
compt + 1
shift - 16
EndIf
count = ((control >> 24) & 3) + 2
offset = quick_local - ((control >> 16) & 255) - 1
While count
count - 1
quick_buffer(quick_local & 255) = quick_buffer(offset & 255)
offset + 1
Debug "Rout2 : $" + Hex(quick_buffer(quick_local & 255),#PB_Byte)
quick_local + 1
Wend
EndIf
Wend
EndProcedure
no_clear_flag = $01 & 1
UnpackQuick()
17 B0 08 51 03 84 90 56 03 00 99 30 58 56
je devrais obtenir celle là :
00 01 00 0A 00 01 00 09 00 0A 00 0A 00 0A 00 0A 00 32 00 0A 00 0A 00
or j'obtiens ça :
00 00 00 0A 00 00 00 09 00 0A 00 0A 00 0A 00 0A 00 32 00 0A 00 0A 00
Le problème semble toujours lié à la dernière partie du code et particulièrement au quick_buffer mais ça, je n'en suis pas sûr car il y a encore des choses qui m'échappent dans le fonctionnement même de ce code
