10 #include <boost/format.hpp>
40 #include "decrunchxipzstub.inc"
42 #define POS_OF_END_OF_CDATA 0x38
43 #define POS_OF_BEGIN_OF_CDATA 0x3d
47 #define POS_OF_DEST 0x6f
49 #define POS_OF_JMP 0x5c
51 #define POS_OF_STOPREADING 0x58
81 for(
int i = x.
bits - 1; i >= 0; --i) {
82 if((x.
data & (1 << i)) != 0) {
101 bool operator<(
const HistEntry &x)
const {
return freq > x.freq; }
124 std::vector<uint8_t> rawdata;
125 std::ifstream inp(fname, std::ios::binary);
129 std::ostringstream out;
130 out <<
"can not open file '" << fname <<
'\'';
131 throw std::runtime_error(out.str());
137 rawdata.push_back(tmp);
141 std::cout <<
"Bytes read (without load address): " << data.
size() << std::endl;
142 std::cout <<
"Load address: " << data.
get_loadaddr() << std::endl;
159 std::array<unsigned long, 256> histo;
165 for(uint8_t i : data) {
168 for(
int i = 0; i < 256; ++i) {
169 shisto.push_back(
HistEntry{
static_cast<uint8_t
>(i), histo[i]});
171 std::sort(shisto.begin(), shisto.end());
185 o <<
'(' << x.freq <<
" * $" << std::hex << (int)x.byte << std::dec <<
')';
201 unsigned long compressed_bytes = 0;
202 unsigned long total_bytes = data.
size();
204 std::for_each(histarr.begin(), histarr.begin() + two_n, [&compressed_bytes](
const HistEntry &x) { compressed_bytes += x.freq; });
205 unsigned long literals = total_bytes - compressed_bytes;
206 float after_compression = 8 * literals;
207 after_compression += n * compressed_bytes;
208 after_compression += total_bytes;
209 after_compression /= 8;
210 std::cout << boost::format(
"Total compressed bytes (n=%d): %5.3f (%.8e:1)\n") % n % after_compression % (total_bytes / after_compression);
211 return after_compression;
229 for(i = 0; i < 256; ++i) {
230 bits[i] =
Bits(i, 8);
232 for(i = 0; i < (1 << n); ++i) {
233 bits[compressable[i].byte] =
Bits(i, n);
253 std::ostream &
write_stub(std::ostream &out,
int n, uint16_t size, uint16_t loadaddr, uint16_t jmp) {
255 std::vector<uint8_t> stub(decrunchxipzstub, decrunchxipzstub + decrunchxipzstub_len);
280 std::copy(stub.begin(), stub.end(), std::ostream_iterator<unsigned char>(out));
296 for(
int i = 0; i < (1 << n); ++i) {
313 std::copy(data.begin(), data.end(), std::ostream_iterator<unsigned char>(out));
334 unsigned long bitstore = 0;
336 std::vector<uint8_t> out;
341 if(compbits[i].bits == 8) {
346 bitstore <<= compbits[i].bits;
347 bit += compbits[i].bits;
348 bitstore |= compbits[i].data;
350 out.push_back(
static_cast<char>(bitstore >> (bit - 8)));
354 std::cout <<
"█" << std::hex << (int)i << std::dec<<
"🠢 " << compbits[i];
359 int fillbits = (bit % 8);
360 bitstore <<= fillbits;
364 out.push_back(
static_cast<char>(bitstore >> (bit - 8)));
378 std::cout <<
"64 most common bytes:\n\t";
379 std::for_each(shisto.begin(), shisto.begin() + 64, [&count](
const HistEntry &i) {
385 std::cout <<
' ' << i;
388 std::cout << std::endl;
402 float minsize = data.
size();
405 for(
int i = 1; i <= 6; ++i) {
425 int main_xipz(
const std::string &inputname,
const std::string &outputname,
bool raw,
int jump) {
430 std::cout <<
"Optimal number of bits: N=" << n << std::endl;
432 uint16_t jumpaddr = jump < 0 ? data.
get_loadaddr() : jump;
433 std::ofstream out(outputname, std::ios::binary);
436 std::cout <<
"Skipping writing the decrunching stub!\n";
438 std::cout <<
"Writing decrunching stub...\n";
441 std::cout << boost::format(
"Writing table, %d bytes...\n") % (1 << n);
443 std::cout << boost::format(
"Writing %u bytes compressed data...\n") % cdata.size();
457 int main_qadz(
const std::string &inputname,
const std::string &outputname,
bool raw,
int jump) {
461 std::vector<uint8_t> compressed(
crunch_qadz(data));
462 std::cout <<
"Compressed size: " << compressed.size() << std::endl;
463 std::ofstream out(outputname);
470 std::cout <<
"Writing decrunching stub...\n";
482 int main(
int argc,
char **argv) {
490 std::cerr <<
"At least one filename must be provided!\n";
495 std::string inpnam(args.
inputs[0]);
498 outnam = inpnam + (args.
raw_given ?
".raw" :
".prg");
503 case algorithm_arg_xipz:
506 case algorithm_arg_qadz:
509 case algorithm__NULL:
510 throw std::logic_error(
"algorithm vanished");
513 catch(
const std::exception &e) {
514 std::cerr <<
"Exception: " << e.what() << std::endl;