From 3f0d5fe2f332814b2f2654d3c13e0a079622151c Mon Sep 17 00:00:00 2001 From: Maurizio Porrato Date: Sun, 22 Oct 2023 14:12:54 +0100 Subject: [PATCH] Use smaller buffers on 16bit targets --- Makefile | 6 ++-- dsk2img.c | 100 ++++++++++++++++++++++++------------------------------ 2 files changed, 48 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index c56f66b..760344d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = clang -CFLAGS ?= -Wall -Wextra -pedantic -std=c89 -O0 -g -pg +CFLAGS ?= -Wall -Wextra -pedantic -std=c89 -Og -g STRIP = strip FORMAT = clang-format -i BIN = dsk2img @@ -8,16 +8,18 @@ TESTS = test-lzw .PHONY: all tests strip clean format all: $(BIN) + tests: $(TESTS) strip: $(BIN) $(STRIP) $^ test-lzw: lzw.o utils.o + dsk2img: lzw.o utils.o clean: - $(RM) $(BIN) $(TESTS) *.o *~ *% + $(RM) $(BIN) $(TESTS) *.o *.exe *~ *% format: $(FORMAT) *.c *.h diff --git a/dsk2img.c b/dsk2img.c index 217de2a..4a4686e 100644 --- a/dsk2img.c +++ b/dsk2img.c @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 2 +#define _POSIX_C_SOURCE 200809L #include "lzw.h" #include "utils.h" #include @@ -17,13 +17,22 @@ #if defined(__DOS__) || defined(__WINDOWS__) || defined(__NT__) || defined(__OS2__) #define DOSLIKE #define DIRSEP '\\' +#include /* For _chsize() */ #else #undef DOSLIKE #define DIRSEP '/' #endif +#ifdef __I86__ +/* Use smaller buffers in 16bit environments */ +#define READ_BUFFER_SIZE 1024 +#define DECOMPRESS_BUFFER_SIZE 4096 +#define COPY_BUFFER_SIZE 8192 +#else #define READ_BUFFER_SIZE 4096 #define DECOMPRESS_BUFFER_SIZE 4096 +#define COPY_BUFFER_SIZE 8192 +#endif #pragma pack(1) struct dskheader { @@ -109,24 +118,21 @@ char* guess_output_filename(const char* input_filename, int is_compressed) void pad_file_to_size(FILE* f, unsigned long size) { - long r; - unsigned long current_pos; + long current_pos; - r = ftell(f); - if (r < 0) { + current_pos = ftell(f); + if (current_pos < 0) { perror("ftell()"); } - current_pos = r; - if (current_pos > size) - printf("ERROR: output file is larger than expected! (%lu vs %lu)\n", current_pos, size); - if (current_pos < size - 1) { - long pos; - - pos = ((long)size) - 1; - fseek(f, pos, SEEK_SET); + if ((unsigned long)current_pos > size) + printf("ERROR: output file is larger than expected! (%ld vs %lu)\n", current_pos, size); + else if ((unsigned long)current_pos != size) { +#ifdef DOSLIKE + _chsize(fileno(f), (long)size); +#else + ftruncate(fileno(f), size); +#endif } - if (current_pos < size) - fputc(0, f); } int valid_header(const struct dskheader* h) @@ -215,63 +221,63 @@ int copy_image_data(FILE* fin, FILE* fout, size_t size, uint32_t* checksum) { unsigned long int copied_bytes; size_t read_count, write_count; - uint8_t* read_buffer = NULL; + uint8_t* copy_buffer = NULL; - read_buffer = (uint8_t*)malloc(READ_BUFFER_SIZE); - if (read_buffer == NULL) { - perror("malloc()"); + copy_buffer = (uint8_t*)malloc(COPY_BUFFER_SIZE); + if (copy_buffer == NULL) { + fputs("Can't allocate read buffer.", stderr); return -1; } for (copied_bytes = 0; copied_bytes < size;) { - read_count = fread(read_buffer, 1, READ_BUFFER_SIZE, fin); + read_count = fread(copy_buffer, 1, COPY_BUFFER_SIZE, fin); if (read_count == 0) { perror("fread()"); - free(read_buffer); + free(copy_buffer); return -2; } - update_checksum(checksum, read_buffer, read_count); - write_count = fwrite(read_buffer, 1, read_count, fout); + update_checksum(checksum, copy_buffer, read_count); + write_count = fwrite(copy_buffer, 1, read_count, fout); if (read_count != write_count) { perror("fwrite()"); - free(read_buffer); + free(copy_buffer); return -3; } copied_bytes += read_count; } - free(read_buffer); + free(copy_buffer); return 0; } int copy_compressed_image_data(FILE* fin, FILE* fout) { size_t read_count, write_count; - uint8_t* read_buffer = NULL; + uint8_t* copy_buffer = NULL; - read_buffer = (uint8_t*)malloc(READ_BUFFER_SIZE); - if (read_buffer == NULL) { - perror("malloc()"); + copy_buffer = (uint8_t*)malloc(COPY_BUFFER_SIZE); + if (copy_buffer == NULL) { + fputs("Can't allocate read buffer.", stderr); return -1; } for (;;) { - read_count = fread(read_buffer, 1, READ_BUFFER_SIZE, fin); + read_count = fread(copy_buffer, 1, COPY_BUFFER_SIZE, fin); if (read_count == 0) { perror("fread()"); - free(read_buffer); + free(copy_buffer); return -2; } - write_count = fwrite(read_buffer, 1, read_count, fout); + write_count = fwrite(copy_buffer, 1, read_count, fout); if (read_count != write_count) { perror("fwrite()"); - free(read_buffer); + free(copy_buffer); return -3; } - if (read_count < READ_BUFFER_SIZE) + if (read_count < COPY_BUFFER_SIZE) break; } - free(read_buffer); + free(copy_buffer); return 0; } @@ -284,20 +290,20 @@ int decompress_image_data(FILE* fin, FILE* fout, size_t size, uint32_t* checksum read_buffer = (uint8_t*)malloc(READ_BUFFER_SIZE); if (read_buffer == NULL) { - perror("malloc()"); + fputs("Can't allocate read buffer.", stderr); return -1; } decompress_buffer = (uint8_t*)malloc(DECOMPRESS_BUFFER_SIZE); if (decompress_buffer == NULL) { - perror("malloc()"); + fputs("Can't allocate decompress buffer.", stderr); free(read_buffer); return -2; } lzw = (struct lzw_ctx*)malloc(sizeof(struct lzw_ctx)); if (lzw == NULL) { - perror("malloc()"); + fputs("Can't allocate lzw_context.", stderr); free(read_buffer); free(decompress_buffer); return -3; @@ -345,7 +351,6 @@ void dsk2img(const char* filename, int no_lzw) long int start_offset; uint32_t checksum; int type_geom; - char *rbuf = NULL, *wbuf = NULL; /* for setvbuf() */ #ifdef DEBUG fprintf(stderr, "Extracting %s\n", filename); @@ -355,12 +360,6 @@ void dsk2img(const char* filename, int no_lzw) if (inf == NULL) return; - rbuf = (char*)malloc(4096); - if (rbuf) - setvbuf(inf, rbuf, _IOFBF, 4096); - else - printf("WARNING: can't allocate read buffer."); - rres = fread(&header, sizeof(header), 1, inf); if (rres != 1) { printf("Short read\n"); @@ -427,12 +426,6 @@ void dsk2img(const char* filename, int no_lzw) goto done; } - wbuf = (char*)malloc(4096); - if (wbuf) - setvbuf(outf, wbuf, _IOFBF, 4096); - else - printf("WARNING: can't allocate write buffer."); - checksum = 0; if (header.magic != MAGIC_DSK_COMPRESSED) { if (copy_image_data(inf, outf, saved_size, &checksum) < 0) @@ -440,7 +433,6 @@ void dsk2img(const char* filename, int no_lzw) } else { if (no_lzw) { copy_compressed_image_data(inf, outf); - goto done; } else { if (decompress_image_data(inf, outf, saved_size, &checksum) < 0) goto done; @@ -459,10 +451,6 @@ done: fclose(inf); if (outname) free(outname); - if (rbuf) - free(rbuf); - if (wbuf) - free(wbuf); } void help(void)