mirror of
https://github.com/aaru-dps/docs.git
synced 2025-12-16 19:24:38 +00:00
227 lines
8.0 KiB
Plaintext
227 lines
8.0 KiB
Plaintext
|
|
|
|||
|
|
*** WRA, WR3 (WRAptor compressed files, and version 3.0 files)
|
|||
|
|
*** Document revision: 1.4
|
|||
|
|
*** Last updated: March 11, 2004
|
|||
|
|
*** Compiler/Editor: Peter Schepers
|
|||
|
|
*** Contributors/sources: Todd Elliott,
|
|||
|
|
Fender Tucker & Doreen Horne (Loadstar)
|
|||
|
|
|
|||
|
|
Written by Bill Lucier (copyright 1995), distributed by Loadstar (on disk
|
|||
|
|
and from the website), and fixed/updated by Doreen Horne, this is an
|
|||
|
|
uncommon compression format as it is a relatively new program. It handles
|
|||
|
|
PRG, SEQ, USR and GEOS files (Sequential and VLIR), but not REL files. As
|
|||
|
|
of this writing, the latest bug fixed version was 3.0B. It is the support
|
|||
|
|
for compressing GEOS files which makes this program special.
|
|||
|
|
|
|||
|
|
Many thanks to Fender Tucker (from Loadstar) and Doreen Horne for their
|
|||
|
|
support on the Wraptor format, as well as authorizing the release of the
|
|||
|
|
source code, and subsequent documentation of the format. I hope this
|
|||
|
|
prolongs the life and usefulness of Wraptor.
|
|||
|
|
|
|||
|
|
Wraptor utilizes a variant of the LZSS (Lempel-Ziv) compression
|
|||
|
|
algorithm, starting at 9 bits per code. The following is a dump of a sample
|
|||
|
|
WRA file. The four bytes at the beginning of the file, "FF 42 4C FF" are
|
|||
|
|
the signature, and preceed each compressed file in the archive. The "42 4C"
|
|||
|
|
are the authors initials, "BL".
|
|||
|
|
|
|||
|
|
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII
|
|||
|
|
----------------------------------------------- ----------------
|
|||
|
|
0000: FF 42 4C FF 50 4F 4F 59 41 4E 00 02 00 82 04 60 <20>BL<42>POOYAN<41>.<2E><>.`
|
|||
|
|
0010: 80 50 01 16 41 59 0C 14 F0 81 0C 47 49 31 11 40 <20>P..AY..<2E><>.GI1.@
|
|||
|
|
0020: 9E 4F 2C 90 49 C2 E2 61 3C 82 44 22 94 84 42 C1 <20>O,<2C>I<EFBFBD><49>a<<3C>D"<22><>B<EFBFBD>
|
|||
|
|
0030: C0 B0 62 00 21 82 02 90 62 0C 61 63 19 43 D4 4D <20><>b<EFBFBD>!<21>.<2E>b.ac.C<>M
|
|||
|
|
0040: 20 92 49 D1 F3 13 41 01 E0 02 78 68 37 1C 0D 40 <20><>I<EFBFBD><49>.A.<2E>.xh7..@
|
|||
|
|
0050: 14 E1 40 00 DD 0B FF 42 4C FF 50 4F 4F 59 41 4E .<2E>@<40><>.<2E>BL<42>POOYAN
|
|||
|
|
0060: 2E 4D 41 49 4E 00 02 7E 0C 0A B0 31 31 00 08 00 .MAIN<49>.~..<2E>11<31>.<2E>
|
|||
|
|
0070: 00 09 40 00 05 2A 00 02 A5 54 3C 81 10 88 00 08 <20><>@<40>.*<2A>.<2E>T<<3C>.<2E><>.
|
|||
|
|
|
|||
|
|
Byte: $00-03: FF 42 4C FF - Compressed file signature "<22>BL<42>"
|
|||
|
|
04-xx: 50 4F 4F 59 41 4E 00 - File name "POOYAN", terminated with
|
|||
|
|
a $00 (null) byte
|
|||
|
|
02 - File type
|
|||
|
|
01 = SEQ
|
|||
|
|
02 = PRG
|
|||
|
|
03 = USR
|
|||
|
|
04 = GEOS
|
|||
|
|
|
|||
|
|
What follows the filetype is compressed file data, up until two bytes
|
|||
|
|
before the next signature, or two bytes to the end of the file, whichever
|
|||
|
|
comes first. The two bytes at the end comprise the 16-bit CRC value.
|
|||
|
|
|
|||
|
|
The Wraptor format does not include information in the header that would
|
|||
|
|
normally be considered important for generic decompression, such as:
|
|||
|
|
|
|||
|
|
1. No original or compressed file sizes
|
|||
|
|
2. No offset to show where the next compressed file starts
|
|||
|
|
3. No version# info, to know if the decompressor you have is the correct
|
|||
|
|
type to uncompress the file. This is determined by the file extension,
|
|||
|
|
with WR3 being the newest. WRA represents version 1.x and 2.x.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The original release of Wraptor (version 1.x) contained a few bugs,
|
|||
|
|
specifically dealing with the compression and decompression of certain GEOS
|
|||
|
|
filetypes, with all of the other file types (PRG, SEQ, USR) being fine.
|
|||
|
|
Version 2.x was released, but more bugs with GEOS files were found. Thus
|
|||
|
|
version 3.x was released.
|
|||
|
|
|
|||
|
|
As of version 3.x, the earlier WRA files are no longer supported, only
|
|||
|
|
the WR3 files. To decode WRA files, you can either use a pre-3.0 version of
|
|||
|
|
Wraptor, or rename the files to end with WR3 and see if version 3 will
|
|||
|
|
unwrap them. If they contain a faulty compressed GEOS file, the file might
|
|||
|
|
not decompress properly.
|
|||
|
|
|
|||
|
|
|
|||
|
|
You can get a list of files contained in a WRA/WR3 file by using one of
|
|||
|
|
the following two methods:
|
|||
|
|
|
|||
|
|
1. Decompress each file in succession, a tedious task at the best of
|
|||
|
|
times. This *is* the method WRAptor uses to display and decompress
|
|||
|
|
files in its archives, and it is very slow!
|
|||
|
|
|
|||
|
|
2. Scan the whole file for the "FF 42 4C FF" signature preceeding each
|
|||
|
|
file, and store the starting offsets. There may be the possibility
|
|||
|
|
that this signature will show up in the normal compressed data, but
|
|||
|
|
the odds are very low.
|
|||
|
|
|
|||
|
|
|
|||
|
|
The Wraptor compression on PRG, SEQ and USR files is very simple to
|
|||
|
|
decode. GEOS files are the exception as they need to be reconstructed
|
|||
|
|
exactly as they were, VLIR chains and all. The following C program explains
|
|||
|
|
how basic decompression works, but not for GEOS:
|
|||
|
|
|
|||
|
|
|
|||
|
|
---------------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
|
|||
|
|
The following code assumes you have already read in the signature,
|
|||
|
|
filename+NULL and filetype byte, and simply want to decode the data.
|
|||
|
|
There is no provision made to decode the GEOS data, or actually show how
|
|||
|
|
to calculate the CRC
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
void main(void)
|
|||
|
|
{
|
|||
|
|
FILE *readfile, *writefile;
|
|||
|
|
|
|||
|
|
int i;
|
|||
|
|
|
|||
|
|
char data, type, tmp, rep_length, read_bitsize;
|
|||
|
|
unsigned buff_pointer, dict_offset;
|
|||
|
|
|
|||
|
|
/* Output stream buffer */
|
|||
|
|
char buffer[(unsigned)32768];
|
|||
|
|
|
|||
|
|
/* Compressed file to decode */
|
|||
|
|
readfile=fopen("compress.wra","rb");
|
|||
|
|
|
|||
|
|
/* Uncompressed output stream */
|
|||
|
|
writefile=fopen("uncompressed","wb");
|
|||
|
|
|
|||
|
|
/* Initial bitsize of the dictionary lookup */
|
|||
|
|
read_bitsize=8;
|
|||
|
|
|
|||
|
|
/* Clear buffer pointer */
|
|||
|
|
buff_pointer=0;
|
|||
|
|
|
|||
|
|
while(1)
|
|||
|
|
{
|
|||
|
|
/* Get compressed yes/no flag (single bit) from the input stream */
|
|||
|
|
type=get_bits(1);
|
|||
|
|
|
|||
|
|
/* Normal unencoded data, preceeded by a zero bit */
|
|||
|
|
if(!type)
|
|||
|
|
{
|
|||
|
|
/* Get normal 8-bit byte */
|
|||
|
|
data=get_bits(8);
|
|||
|
|
|
|||
|
|
/* Add data to output buffer */
|
|||
|
|
buffer[buff_pointer]=data;
|
|||
|
|
|
|||
|
|
/* Calculate the CRC as we read in the data */
|
|||
|
|
calc_crc(data);
|
|||
|
|
|
|||
|
|
/* Move pointer for next data byte */
|
|||
|
|
buff_pointer++;
|
|||
|
|
|
|||
|
|
/* Has the output buffer filled up? */
|
|||
|
|
if(buff_pointer>=(unsigned)32768)
|
|||
|
|
{
|
|||
|
|
/* Write out the buffer to the output file */
|
|||
|
|
/* Here is where we would decode the GEOS file structure */
|
|||
|
|
fwrite(buffer, 1, buff_pointer, writefile);
|
|||
|
|
|
|||
|
|
/* Reset buffer pointer for another block of data */
|
|||
|
|
buff_pointer=0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Encoded data, preceeded by a one bit */
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* Get dictionary offset */
|
|||
|
|
dict_offset=get_bits(read_bitsize);
|
|||
|
|
|
|||
|
|
/* A "0" offset, either an EOF or increase read_bitsize by one */
|
|||
|
|
if(!dict_offset)
|
|||
|
|
{
|
|||
|
|
/* Check next bit */
|
|||
|
|
tmp=get_bits(1);
|
|||
|
|
|
|||
|
|
/* If next bit clear, we are at the end of the compressed file */
|
|||
|
|
if(!tmp)
|
|||
|
|
{
|
|||
|
|
/* Write output buffer to the output file */
|
|||
|
|
/* Here is where we would decode the GEOS file structure */
|
|||
|
|
fwrite(buffer, 1, buff_pointer,writefile);
|
|||
|
|
buff_pointer=0;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
/* If next bit set, increase read_bitsize by one */
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
read_bitsize++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* We have a valid offset, get the length */
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* Length of the stored string, 5 bits */
|
|||
|
|
rep_length=get_bits(5);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
Copy the data from in the buffer at the dict_offset position to
|
|||
|
|
the end of the buffer
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
for(i=0;i<rep_length;i++)
|
|||
|
|
{
|
|||
|
|
buffer[buff_pointer]=buffer[dict_offset-1+i];
|
|||
|
|
buff_pointer++;
|
|||
|
|
|
|||
|
|
/* Write buffer to output file */
|
|||
|
|
/* Here is where we would decode the GEOS file structure */
|
|||
|
|
if(buff_pointer>=(unsigned)32768)
|
|||
|
|
{
|
|||
|
|
fwrite(buffer, 1, buff_pointer,writefile);
|
|||
|
|
buff_pointer=0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Get the two-byte CRC which follows the compressed data stream */
|
|||
|
|
get_crc();
|
|||
|
|
|
|||
|
|
/* Make sure the CRC you read matches the one you calculated */
|
|||
|
|
check_crc();
|
|||
|
|
|
|||
|
|
fclose(readfile);
|
|||
|
|
fclose(writefile);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|