/
unjzp.cpp
139 lines (127 loc) · 3.42 KB
/
unjzp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdio.h>
#include <string.h>
#include <util/BinFile.h>
#include "jzp.h"
#include "CBitReader.h"
#include "COutBuffer.h"
#include "errors.h"
int decompress( const void *inbuf, const unsigned inlen, void *outbuf)
{
const JZPHDR *hdr = static_cast<const JZPHDR *>(inbuf);
if (hdr->decomp_size==0)
return 0;
unsigned char dist_width = hdr->dist_width;
unsigned dist_max = 1<<dist_width;
unsigned size_width = hdr->size_width>>4;
unsigned min_size = hdr->size_width & 0x0F;
const unsigned char *ptr = static_cast<const unsigned char *>(inbuf);
CBitReader *in = new CBitReader(ptr+sizeof(JZPHDR), swapl(hdr->comp_size) - sizeof(JZPHDR));
COutBuffer *out = new COutBuffer(outbuf, swapl(hdr->decomp_size), dist_max);
try
{
while(!(out->full() || in->empty()))
{
if (in->get(1)==1)
{
unsigned char lit = in->get(8);
//printf("lit %02X\n", lit);
out->put(lit);
}
else
{
unsigned short dist = in->get(dist_width);
unsigned char size = in->get(size_width)+min_size;
//printf("repeat %04X[%02X]\n", dist, size);
out->repeat(dist, size);
}
}
}
catch (Overflow)
{
puts("Output overflow detected !");
}
catch (Misalign)
{
puts("Buffer misalign detected !");
}
catch (NegativeDistanse)
{
puts("Negative distanse detected !");
}
catch (OutOfBounds)
{
puts("Out of bounds !");
}
if (in->byte_empty() && out->full())
{
puts("LZSS: OK");
}
else
{
if (in->empty())
puts(" IN is empty");
else
printf(" IN used %X of %lu\n", in->used(), swapl(hdr->comp_size) - sizeof(JZPHDR));
if (out->full())
puts(" OUT is full");
else
printf(" OUT used %X of %X\n", out->used(), swapl(hdr->decomp_size));
}
int res = out->used();
delete out;
delete in;
return res;
}
int main(int argc, char *argv[])
{
if ((argc!=3) && (argc!=4))
{
printf("Usage: %s <in.jzp> <out.bin> [out_rev.txt]\n", argv[0]);
return 1;
}
unsigned insize;
unsigned char *inbuf = LoadBinFile(argv[1], &insize);
if (!inbuf)
{
puts("Can't open input file !");
return 1;
}
const JZPHDR *hdr = (const JZPHDR *)inbuf;
if (strncmp(hdr->magic, "AGLTZIP", 8))
{
puts("Not a JZP !");
delete inbuf;
return 1;
}
unsigned ck = jzp_checksum(inbuf, swapl(hdr->comp_size));
if (ck!=0)
{
puts("Checksum error ! Input file is corrupt !");
delete inbuf;
return 1;
}
puts(hdr->revision);
if (argc==4) //save revision
{
SaveBinFile(argv[3], hdr->revision, strlen(hdr->revision));
}
unsigned decomp_size = swapl(hdr->decomp_size);
unsigned char *outbuf = new unsigned char[decomp_size];
puts("Decompressing...");
if (decompress(inbuf, insize, outbuf)!=decomp_size)
{
puts("Decompression error !");
}
ck = jzp_checksum(outbuf, decomp_size);
if (ck==hdr->decomp_checksum)
{
puts("CHECKSUM: OK");
}
else
{
printf("CHECKSUM: FAIL\ncalc checksum: %08X, hdr checksum: %08X\n", swapl(ck), swapl(hdr->decomp_checksum));
}
SaveBinFile(argv[2], outbuf, decomp_size);
delete outbuf;
delete inbuf;
}