From 4c129f3bddc87508554227b961e382ee8ce3060f Mon Sep 17 00:00:00 2001 From: hkc Date: Sun, 18 Sep 2022 16:21:18 +0300 Subject: [PATCH] Initial DD --- .gitignore | 3 +++ Makefile | 13 +++++++++++++ bitstream.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ bitstream.h | 25 +++++++++++++++++++++++++ main.c | 5 +++++ test_bitstream.c | 22 ++++++++++++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 bitstream.c create mode 100644 bitstream.h create mode 100644 main.c create mode 100644 test_bitstream.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ace5795 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +test_bitstream +main +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..50d7851 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +OBJECTS := bitstream.o + +clean: + $(RM) *.o test_bitstream main + +run_%: % + ./$^ + +test_%: test_%.c $(OBJECTS) + $(CC) $^ -o $@ + +%.o: %.c + $(CC) $^ -c -o $@ diff --git a/bitstream.c b/bitstream.c new file mode 100644 index 0000000..2ef15ed --- /dev/null +++ b/bitstream.c @@ -0,0 +1,44 @@ +#include "./bitstream.h" +#include + +BitStream bitstream_load_from_file(FILE *fp) { + fseek(fp, SEEK_END, 0); + size_t length = ftell(fp); + fseek(fp, SEEK_SET, 0); + BitStream bs = bitstream_init_empty(length); + fread(bs.buffer, 1, length, fp); + return bs; +} + +BitStream bitstream_init_empty(size_t size_in_bytes) { + return (BitStream){ + .buffer = malloc(size_in_bytes), + .buffer_size = size_in_bytes, + .offset = 0 + }; +} + +bool bitstream_end(BitStream bs) { + return (bs.offset >> 3) >= bs.buffer_size; +} + +uint8_t bitstream_get(BitStream bs, off_t offset) { + return bs.buffer[offset >> 3] & (0x80 >> (offset & 7)) ? 1 : 0; +} + + +uint8_t bitstream_next(BitStream *bs) { + uint8_t val = bitstream_get(*bs, bs->offset); + bs->offset++; + return val; +} + +void bitstream_set(BitStream bs, off_t offset, uint8_t value) { + bs.buffer[offset >> 3] &= ~(0x80 >> (offset & 7)); + bs.buffer[offset >> 3] |= (value ? 1 : 0) * (0x80 >> (offset & 7)); +} + +void bitstream_unload(BitStream *bs) { + free(bs->buffer); + bs->buffer = 0; +} diff --git a/bitstream.h b/bitstream.h new file mode 100644 index 0000000..b1633b1 --- /dev/null +++ b/bitstream.h @@ -0,0 +1,25 @@ +#ifndef _BITSTREAM_H_ +#define _BITSTREAM_H_ + +#include +#include +#include +#include + +typedef struct bit_stream { + uint8_t *buffer; + size_t buffer_size; + off_t offset; +} BitStream; + +BitStream bitstream_load_from_file(FILE *fp); +BitStream bitstream_init_empty(size_t size_in_bytes); + +uint8_t bitstream_get(BitStream bs, off_t offset); +uint8_t bitstream_next(BitStream *bs); +bool bitstream_end(BitStream bs); +void bitstream_set(BitStream bs, off_t offset, uint8_t value); + +void bitstream_unload(BitStream *bs); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..00eb67c --- /dev/null +++ b/main.c @@ -0,0 +1,5 @@ +// x-run: make clean all run +#include "./bitstream.h" + +int main(void) { +} diff --git a/test_bitstream.c b/test_bitstream.c new file mode 100644 index 0000000..a1ccdaf --- /dev/null +++ b/test_bitstream.c @@ -0,0 +1,22 @@ +// x-run: make clean test_bitstream run_test_bitstream +#include "./bitstream.h" + +int main(void) { + BitStream bs = bitstream_init_empty(16 * 2); + bitstream_set(bs, 16 * 0 + 0, 1); + bitstream_set(bs, 16 * 2 + 2, 1); + bitstream_set(bs, 16 * 4 + 4, 1); + bitstream_set(bs, 16 * 8 + 8, 1); + bitstream_set(bs, 16 * 4 + 4, 0); + printf(" "); + for (int i = 0; i < 16; i++) printf("%2x", i); + printf("\n"); + for (int i = 0; !bitstream_end(bs); i++) { + if (i % 16 == 0) printf("%2x", i >> 4); + printf("\033[%dm ", bitstream_next(&bs) \ + ? (i >> 4 & 1 ? 47 : 107) \ + : (i >> 4 & 1 ? 40 : 100)); + if (i % 16 == 15) printf("\033[0m\n"); + } + bitstream_unload(&bs); +}