From b55c5a4192c3bde642929fe9fb5764660911405c Mon Sep 17 00:00:00 2001 From: Hizenberg Date: Sun, 14 Apr 2024 22:18:05 +0530 Subject: [PATCH] clib --- .gitignore | 2 +- clib/bitio.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++ clib/bitio.h | 29 ++++++++ clib/errhand.c | 16 +++++ clib/errhand.h | 6 ++ clib/main-c.c | 121 +++++++++++++++++++++++++++++++++ clib/main-e.c | 74 ++++++++++++++++++++ clib/main.h | 11 +++ 8 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 clib/bitio.c create mode 100644 clib/bitio.h create mode 100644 clib/errhand.c create mode 100644 clib/errhand.h create mode 100644 clib/main-c.c create mode 100644 clib/main-e.c create mode 100644 clib/main.h diff --git a/.gitignore b/.gitignore index f792e46..97310df 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ *.vcxproj.filters *.vcxproj.user x64 -clib \ No newline at end of file +.vs \ No newline at end of file diff --git a/clib/bitio.c b/clib/bitio.c new file mode 100644 index 0000000..21e5e61 --- /dev/null +++ b/clib/bitio.c @@ -0,0 +1,178 @@ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include "bitio.h" +#include "errhand.h" + +#define PACIFIER_COUNT 2047 + +BIT_FILE* OpenOutputBitFile(char* name) { + + BIT_FILE* bit_file; + bit_file = (BIT_FILE*)calloc(1, sizeof(BIT_FILE)); + if (bit_file == NULL) + return bit_file; + + bit_file->file = fopen(name, "wb"); + bit_file->rack = 0; + bit_file->mask = 0x80; + bit_file->pacifier_counter = 0; + return bit_file; + +} + +BIT_FILE* OpenInputBitFile(char* name) { + + BIT_FILE* bit_file; + bit_file = (BIT_FILE*)calloc(1, sizeof(BIT_FILE)); + if (bit_file == NULL) + return bit_file; + + bit_file->file = fopen(name, "rb"); + bit_file->rack = 0; + bit_file->mask = 0x80; + bit_file->pacifier_counter = 0; + return bit_file; + +} + +void CloseOutputBitFile(BIT_FILE* bit_file) { + + if (bit_file->mask != 0x80) { + if (putc(bit_file->rack, bit_file->file) != bit_file->rack) + fatal_error("Fatal error in CloseBitFile!\n"); + } + + fclose(bit_file->file); + free((char*)bit_file); + +} + +void CloseInputBitFile(BIT_FILE* bit_file) { + + fclose(bit_file->file); + free((char*)bit_file); + +} + +void OutputBit(BIT_FILE* bit_file, int bit) { + + if (bit) { + bit_file->rack |= bit_file->mask; + } + + bit_file->mask >>= 1; + + if (bit_file->mask == 0) { + if (putc(bit_file->rack, bit_file->file) != bit_file->rack) { + fatal_error("Fatal error in OutputBit!\n"); + } + else if ((bit_file->pacifier_counter++ & PACIFIER_COUNT) == 0) { + putc('.', stdout); + } + bit_file->rack = 0; + bit_file->mask = 0x80; + } + +} + +void OutputBits(BIT_FILE* bit_file, unsigned long code, int count) { + + unsigned long mask; + + mask = 1L << (count - 1); + + while (mask != 0) { + if (mask & code) { + bit_file->rack |= bit_file->mask; + } + + bit_file->mask >>= 1; + + if (bit_file->mask == 0) { + if (putc(bit_file->rack, bit_file->file) != bit_file->rack) { + fatal_error("Fatal error in OuputBit!\n"); + } + else if ((bit_file->pacifier_counter++ & PACIFIER_COUNT) == 0) { + putc('.', stdout); + } + + bit_file->rack = 0; + bit_file->mask = 0x80; + } + + mask >>= 1; + } +} + +int InputBit(BIT_FILE* bit_file) { + + int value; + + if (bit_file->mask == 0x80) { + bit_file->rack = getc(bit_file->file); + if (bit_file->rack == EOF) { + fatal_error("Fatal error in InputBit!\n"); + } + + if ((bit_file->pacifier_counter++ & PACIFIER_COUNT) == 0) { + putc('.', stdout); + } + } + + value = bit_file->rack & bit_file->mask; + bit_file->mask >>= 1; + if (bit_file->mask == 0) { + bit_file->mask = 0x80; + } + + return value ? 1 : 0; +} + +unsigned long InputBits(BIT_FILE* bit_file, int bit_count) { + + unsigned long mask; + unsigned long return_value; + + mask = 1L << (bit_count - 1); + return_value = 0; + + while (mask != 0) { + if (bit_file->mask == 0x80) { + bit_file->rack = getc(bit_file->file); + if (bit_file->rack == EOF) + fatal_error("Fatal error in InputBits!\n"); + + if ((bit_file->pacifier_counter++ & PACIFIER_COUNT) == 0) + putc('.', stdout); + } + + if (bit_file->rack & bit_file->mask) + return_value |= mask; + + mask >>= 1; + bit_file->mask >>= 1; + if (bit_file->mask == 0) + bit_file->mask = 0x80; + } + + return return_value; +} + + +void FilePrintBinary(FILE* file, unsigned int code, int bits) { + + unsigned int mask; + mask = 1 << (bits - 1); + while (mask != 0) { + if (code & mask) + fputc('1', file); + else + fputc('0', file); + + mask >>= 1; + } +} diff --git a/clib/bitio.h b/clib/bitio.h new file mode 100644 index 0000000..f7b3690 --- /dev/null +++ b/clib/bitio.h @@ -0,0 +1,29 @@ +#ifndef _BITIO_H +#define _BITIO_H + +#include + +typedef struct bit_file { + + FILE* file; + unsigned char mask; + int rack; + int pacifier_counter; + +} BIT_FILE; + + +BIT_FILE* OpenInputBitFile(char* name); +BIT_FILE* OpenOutputBitFile(char* name); +void OutputBit(BIT_FILE* bit_file, int bit); +void OutputBits(BIT_FILE* bit_file, unsigned long code, int count); + +int InputBit(BIT_FILE* bit_file); +unsigned long InputBits(BIT_FILE* bit_file, int bit_count); + + +void CloseInputBitFile(BIT_FILE* bit_file); +void CloseOutputBitFile(BIT_FILE* bit_file); +void FilePrintBinary(FILE* file, unsigned int code, int bits); + +#endif /* _BITIO_H */ \ No newline at end of file diff --git a/clib/errhand.c b/clib/errhand.c new file mode 100644 index 0000000..24eba65 --- /dev/null +++ b/clib/errhand.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include "errhand.h" + + +void fatal_error(char* fmt, ...) { + + va_list argptr; + va_start(argptr, fmt); + printf("Fatal error: "); + vprintf(fmt, argptr); + va_end(argptr); + exit(EXIT_FAILURE); + +} \ No newline at end of file diff --git a/clib/errhand.h b/clib/errhand.h new file mode 100644 index 0000000..cddfb01 --- /dev/null +++ b/clib/errhand.h @@ -0,0 +1,6 @@ +#ifndef _ERRHAND_H +#define _ERRHAND_H + +void fatal_error(char* fmt, ...); + +#endif /* _ERRHAND_H */ \ No newline at end of file diff --git a/clib/main-c.c b/clib/main-c.c new file mode 100644 index 0000000..e992806 --- /dev/null +++ b/clib/main-c.c @@ -0,0 +1,121 @@ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include +#include "bitio.h" +#include "errhand.h" +#include "main.h" + +void usage_exit(char* prog_name); +void print_ratios(char* input, char* output); +long file_size(char* name); + +/* main function to compress file (any file) */ +int main(int argc, char* argv[]) { + + BIT_FILE* output; + FILE* input; + + /* Function to set buffer for standard output (i.e. console)*/ + /* setbuf(FILE*, char*) */ + setbuf(stdout, NULL); + /* Here, it currently don't have any buffer to cache data. (bcoze of NULL) */ + + if (argc < 3) + usage_exit(argv[0]); + + input = fopen(argv[1], "rb"); + + if (input == NULL) + fatal_error("Error opening %s for input\n", argv[1]); + + output = OpenOutputBitFile(argv[2]); + + if (output == NULL) + fatal_error("Error opening %s for output\n", argv[2]); + + printf("\nCompressing %s to %s\n", argv[1], argv[2]); + printf("Using %s\n", CompressionName); + + CompressFile(input, output, argc - 3, argv + 3); + CloseOutputBitFile(output); + + fclose(input); + print_ratios(argv[1], argv[2]); + + return 0; +} +/* main function to compress file (any file) */ + + + +void usage_exit(char* prog_name) { + char* short_name; + char* extension; + + short_name = strrchr(prog_name, '\\'); + + if (short_name == NULL) + short_name = strrchr(prog_name, '/'); + if (short_name == NULL) + short_name = strrchr(prog_name, ':'); + if (short_name != NULL) + short_name++; + else + short_name = prog_name; + + extension = strrchr(short_name, '.'); + + if (extension != NULL) + *extension = '\0'; + + printf("\nUsage: %s %s\n", short_name, Usage); + exit(EXIT_SUCCESS); +} + + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +long file_size(char* name) { + + long eof_ftell; + FILE* file; + + file = fopen(name, "r"); + + if (file == NULL) + return 0L; + + fseek(file, 0L, SEEK_END); + eof_ftell = ftell(file); + fclose(file); + return eof_ftell; + +} + +void print_ratios(char* input, char* output) { + + long input_size; + long output_size; + + int ratio; + + input_size = file_size(input); + + if (input_size == 0) + input_size = 1; + + output_size = file_size(output); + + ratio = 100 - (int)(output_size * 100L / input_size); + printf("\nInput bytes: %ld\n", input_size); + printf("Output bytes: %ld\n", output_size); + if (output_size == 0) + output_size = 1; + printf("Compression ratio: %d\n", ratio); +} \ No newline at end of file diff --git a/clib/main-e.c b/clib/main-e.c new file mode 100644 index 0000000..c08629c --- /dev/null +++ b/clib/main-e.c @@ -0,0 +1,74 @@ +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#endif + + +#include +#include +#include +#include "bitio.h" +#include "errhand.h" +#include "main.h" + +void usage_exit(char* prog_name); + +/*main function for expansion of file (any file) */ +int main(int argc, char* argv[]) { + + FILE* output; + BIT_FILE* input; + + setbuf(stdout, NULL); + + if (argc < 3) + usage_exit(argv[0]); + input = OpenInputBitFile(argv[1]); + + if (input == NULL) + fatal_error("Error opening %s for input\n", argv[1]); + + output = fopen(argv[2], "wb"); + + if (output == NULL) + fatal_error("Error opening %s for output\n", argv[2]); + + printf("\nExpanding %s to %s\n", argv[1], argv[2]); + + printf("Using %s\n", CompressionName); + + argc -= 3; + argv += 3; + + ExpandFile(input, output, argc, argv); + CloseInputBitFile(input); + + fclose(output); + + putc('\n', stdout); + return 0; +} +/* main function for expansion of file (any file) */ + +void usage_exit(char* prog_name) { + + char* short_name; + char* extension; + + short_name = strrchr(prog_name, '\\'); + if (short_name == NULL) + short_name = strrchr(prog_name, '/'); + if (short_name == NULL) + short_name = strrchr(prog_name, ':'); + if (short_name != NULL) + short_name++; + else + short_name = prog_name; + + extension = strrchr(short_name, '.'); + + if (extension != NULL) + *extension = '\0'; + + printf("\nUsage: %s %s\n", short_name, Usage); + exit(EXIT_SUCCESS); +} \ No newline at end of file diff --git a/clib/main.h b/clib/main.h new file mode 100644 index 0000000..93521f4 --- /dev/null +++ b/clib/main.h @@ -0,0 +1,11 @@ +#ifndef _MAIN_H +#define _MAIN_H + +void CompressFile(FILE* input, BIT_FILE* output, int argc, char* argv[]); +void ExpandFile(BIT_FILE* input, FILE* output, int argc, char* argv[]); + +extern char* Usage; +extern char* CompressionName; + + +#endif /* _MAIN_H */ \ No newline at end of file