12
Name:
Anonymous
2011-10-12 12:36
#include <stdio.h>
#define chkb(o,p) ((o>>p)&1)
#define getb0(b) ((b >> 0) & 3)
#define getb1(b) ((b >> 2) & 3)
#define getb2(b) ((b >> 4) & 3)
#define getb3(b) ((b >> 6) & 3)
unsigned long long fsize(unsigned char* filename) {
FILE* tfile = fopen(filename, "rb");
if (!tfile) {
perror(filename);
return 0;
}
fseek(tfile, 0, SEEK_END);
unsigned long long sz = (unsigned long long)(ftell(tfile));
fclose(tfile);
return sz;
}
unsigned char* getcontent(unsigned char*filename) { //file to buffer
unsigned long long size = fsize(filename); //
if (!size) {
perror("Zero length content");
return NULL;
}
unsigned char* res = malloc(size);
if (!res) {
perror("Malloc failure");
return NULL;
}
FILE* inpfile = fopen(filename, "rb");
if (!inpfile) {
perror("File cannot be read");
return NULL;
}
unsigned long long findex = (unsigned long long)fread(res, 1, size, inpfile);
fclose(inpfile);
if (findex != size) {
perror("size mismatch");
return NULL;
}
return res;
}
unsigned int int2b(unsigned int v) { // 32-bit value to find the log2 of
static const unsigned int b[] = {0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0,
0xFF00FF00, 0xFFFF0000
};
unsigned int r = (v & b[0]) != 0;
r |= ((v & b[4]) != 0) << 4;
r |= ((v & b[3]) != 0) << 3;
r |= ((v & b[2]) != 0) << 2;
r |= ((v & b[1]) != 0) << 1;
return r;
}
int main(int argc, char**argv) {
if (!argv[1]) {
printf("Syntax: cmp inputfile [-d=decode]");
exit(1);
}
#if 0 /* Decode: does not work. */
if (argv[2] && !strcmp(argv[2], "-d")) { // Decode data + bitmap
unsigned char* bitfile = getcontent("Bitmapx16");
unsigned char* datafile = getcontent("Data");
unsigned long long xsize = fsize("Bitmapx16");
unsigned long long btsize = fsize("Data");
FILE* result = fopen("Result", "wb");
if (!bitfile || !datafile || !result) {
perror("File error");
exit(2);
}
// convert into n1 byte nib(avoids corruption)
unsigned char* expbit = malloc(btsize * 4);
unsigned long long n8;
for (n8 = 0; n8 < btsize; n8++) {
expbit[n8 * 4] = getb0(datafile[n8]);
expbit[n8 * 4 + 1] = getb1(datafile[n8]);
expbit[n8 * 4 + 2] = getb2(datafile[n8]);
expbit[n8 * 4 + 3] = getb3(datafile[n8]);
}
unsigned char bitsave = 0, s0, s1, s2, s3; // read output nib
unsigned long long m, dpos = 0;
unsigned int a2, cbit;
for (m = 0; m < xsize; m++) {
for (a2 = 0; a2 < 8; a2++) { // read bit
cbit = chkb(bitfile[m], a2); // current bit:
if (cbit) { // read three, write four, nib pos never changes due expbit array
s0 = expbit[dpos++];
s1 = expbit[dpos++];
s2 = expbit[dpos++];
bitsave = (s0) | (s1 << 2) | (s2 << 4) | ((s0 ^ 3) << 6);
fputc(bitsave, result);
} else { // read four, write four,
s0 = expbit[dpos++];
s1 = expbit[dpos++];
s2 = expbit[dpos++];
s3 = expbit[dpos++];
bitsave = (s0) | (s1 << 2) | (s2 << 4) | (s3 << 6);
fputc(bitsave, result);
}
} // iloop end
}
printf("Decoded to file Result");
exit(10);
}
#endif
unsigned long long inpsize = fsize(argv[1]);
if (!inpsize) {
perror("input size invalid");
return;
};
unsigned char* input = getcontent(argv[1]);
unsigned char* output = calloc(inpsize / 8 + 1, 1);
if (!input) {
perror("input invalid");
return;
}
FILE* bitfile = fopen("Bitmapx16", "wb");
if (!bitfile) {
perror("File write failed");
return;
};
FILE* datafile = fopen("Data", "wb");
if (!bitfile) {
perror("File write failed");
return;
};
unsigned long long c, total = 0, opos = 0;
unsigned int j;
unsigned char l0, l1, l2, l3, bitsave = 0, bitpos = 0, startnib = 0;
for (c = 1; c < inpsize; c++) {
l0 = getb0(input[c]);
l1 = getb1(input[c]);
l2 = getb2(input[c]);
l3 = getb3(input[c]); //opt
if (l0 ^ 3 == l3) {
total++;
switch (startnib) { //
case 0:
bitsave |= (l0);
bitsave |= (l1 << 2);
bitsave |= (l2 << 4);;
startnib = 3;
break;
case 1:
bitsave |= (l0 << 2);
bitsave |= (l1 << 4);
bitsave |= (l2 << 6);
fputc(bitsave, datafile);
bitsave = 0;
startnib = 0;
break;
case 2:
bitsave |= (l0 << 4);
bitsave |= (l1 << 6);
fputc(bitsave, datafile);
bitsave = 0;
bitsave |= (l2);
startnib = 1;
break;
case 3:
bitsave |= (l0 << 6);
fputc(bitsave, datafile);
bitsave = 0;
bitsave |= (l1);
bitsave |= (l2 << 2);
startnib = 2;
break;
default:
break;
}
output[opos] |= (1 << (bitpos));
} else {
switch (startnib) {
case 0:
bitsave |= (l0);
bitsave |= (l1 << 2);
bitsave |= (l2 << 4);
bitsave |= (l3 << 6);
fputc(bitsave, datafile);
bitsave = 0;;
break;
case 1:
bitsave |= (l0 << 2);
bitsave |= (l1 << 4);
bitsave |= (l2 << 6);
fputc(bitsave, datafile);
bitsave = 0;
bitsave |= (l3);;
break;
case 2:
bitsave |= (l0 << 4);
bitsave |= (l1 << 6);
fputc(bitsave, datafile);
bitsave = 0;
bitsave |= (l2);
bitsave |= (l3 << 2);;
break;
case 3:
bitsave |= (l0 << 6);
fputc(bitsave, datafile);
bitsave = 0;
bitsave |= (l1);
bitsave |= (l2 << 2);
bitsave |= (l2 << 4);
break;
default:
break;
}
}
if (++bitpos == 8) {
bitpos = 0;
opos++;
}
}
fwrite(output, 1, inpsize / 8 + 1, bitfile);
printf("Total bytes saved: %llu\n", total / 4);
}
It still doesn't make sense.