diff --git a/base16384.c b/base16384.c new file mode 100644 index 0000000..05f1054 --- /dev/null +++ b/base16384.c @@ -0,0 +1,32 @@ +#include +#include +#include "base16384.h" + +#define CHOICE argv[1][1] +#define READ argv[2] +#define WRITE argv[3] + +int main(int argc, char **argv){ + FILE *fp = NULL; + FILE *fpo = NULL; + + if(argc != 4){ + fputs("Usage: -[e|d] inputfile outputfile", stderr); + fputs(" -e encode", stderr); + fputs(" -d decode", stderr); + exit(EXIT_FAILURE); + } + + fp = fopen(READ, "rb"); + fpo = fopen(WRITE, "wb"); + if(!fp || !fpo){ + fputs("IO error!", stderr); + exit(EXIT_FAILURE); + } + switch(CHOICE){ + case 'e': encode(fp, fpo); break; + case 'd': decode(fp, fpo); break; + default: break; + } + return 0; +} diff --git a/base16384.exe b/base16384.exe new file mode 100644 index 0000000..140d4a5 Binary files /dev/null and b/base16384.exe differ diff --git a/base16384.h b/base16384.h new file mode 100644 index 0000000..b1e0945 --- /dev/null +++ b/base16384.h @@ -0,0 +1,53 @@ +#include "bitio.h" +#define HEAD 0x4E +BIT outbuf; +unsigned char buf[BUFSIZ]; +void push(int istrue, FILE *fpo, int offset){ + if(!~pushbit(&outbuf, istrue)){ + if(offset) for(int i = 0; i < BITBUFSIZE; i += 2) outbuf.b[i] += offset; + fwrite(outbuf.b, sizeof(char), BITBUFSIZE, fpo); + outbuf.p = 0; + pushbit(&outbuf, istrue); + } +} +void encode(FILE *fp, FILE *fpo){ + int cnt = 0; + + fputc(0xFE, fpo); + fputc(0xFF, fpo); + while((cnt = fread(buf, sizeof(char), BUFSIZ, fp))){ + for(int i = 0; i < cnt * 8; i++){ + if(!(outbuf.p % 16)){ + push(0, fpo, HEAD); + push(0, fpo, HEAD); + } + push(buf[i / 8] & (128u >> (i % 8)), fpo, HEAD); + } + } + if(outbuf.p){ + outbuf.b[outbuf.p / 8] &= ~(255u >> outbuf.p % 8); + for(int i = 0; i < outbuf.p / 8 + 1; i += 2) outbuf.b[i] += HEAD; + fwrite(outbuf.b, sizeof(char), (outbuf.p % 8)?outbuf.p / 8 + 1:outbuf.p / 8 , fpo); + if(((outbuf.p % 8)?outbuf.p / 8 + 1:outbuf.p / 8) % 2) fputc(0, fpo); + for(int i = 0; i < outbuf.p % 8; i++) fputc('=', fpo); + } +} +void decode(FILE *fp, FILE *fpo){ + int cnt = 0; + char ch = '='; + while((cnt = fread(buf, sizeof(char), BUFSIZ, fp))){ + int cnt8 = cnt * 8; + while(!feof(fp) && (ch = fgetc(fp)) == '=') cnt8 -= 7; + if(ch != '=') {ungetc(ch, fp); ch = '=';} + while(feof(fp) && buf[cnt - 1] == '=' && buf[cnt - 2] == '=') {cnt8 -= 7; cnt -= 2;} + if(cnt8 % 8) cnt8 -= 8; + for(int i = ((buf[0] == 0xFE)?16:0); i < cnt8; i++){ + if(!(i % 16)){ + buf[i / 8] -= HEAD; + i += 2; + } + push(buf[i / 8] & (128u >> (i % 8)), fpo, 0); + } + } + if(outbuf.p) fwrite(outbuf.b, sizeof(char), outbuf.p / 8 + ((outbuf.p % 8)?1:0), fpo); +} diff --git a/bitio.h b/bitio.h new file mode 100644 index 0000000..a816dc6 --- /dev/null +++ b/bitio.h @@ -0,0 +1,48 @@ +//bitio.h +//made by fumiama +//20200413 +#include +#include +#ifndef BITBUFSIZE +#define BITBUFSIZE 1024 +#endif +struct BIT{ + char b[BITBUFSIZE]; + int p; +}; +typedef struct BIT BIT; + +int pushbit(BIT *buffer, const int isture){ + if(buffer->p >= BITBUFSIZE * 8) return EOF; + else if(isture) buffer->b[buffer->p / 8] |= 128u >> buffer->p % 8; + else buffer->b[buffer->p / 8] &= ~(128u >> buffer->p % 8); + buffer->p++; + return isture; +} + +int fpushbit(BIT *buffer, FILE *fp){ + memset(buffer, 0, sizeof(BIT)); + if((buffer->p = fread(buffer->b, sizeof(char), BITBUFSIZE, fp)) && feof(fp)) + buffer->p = (buffer->p - 2) * 8 + buffer->b[buffer->p - 1] + 1; + else buffer->p *= 8; + return buffer->p; +} + +int changebit(BIT *buffer, const int isture, const int position){ + if(position >= buffer->p) return EOF; + else if(isture) buffer->b[position / 8] |= 128u >> position % 8; + else buffer->b[position / 8] &= ~(128u >> position % 8); + buffer->p++; + return isture; +} + +int readbit(const BIT *buffer, const int position){ + if(position >= buffer->p) return EOF; + else return buffer->b[position / 8] & (128u >> position % 8); +} + +int popbit(BIT *buffer){ + if(buffer->p >= BITBUFSIZE * 8 || buffer->p < 0) return EOF; + buffer->p--; + return buffer->b[(buffer->p+1) / 8] & (128u >> (buffer->p+1) % 8); +}