Use smaller buffers on 16bit targets

This commit is contained in:
Maurizio Porrato 2023-10-22 14:12:54 +01:00
parent c183681289
commit 3f0d5fe2f3
2 changed files with 48 additions and 58 deletions

View File

@ -1,5 +1,5 @@
CC = clang CC = clang
CFLAGS ?= -Wall -Wextra -pedantic -std=c89 -O0 -g -pg CFLAGS ?= -Wall -Wextra -pedantic -std=c89 -Og -g
STRIP = strip STRIP = strip
FORMAT = clang-format -i FORMAT = clang-format -i
BIN = dsk2img BIN = dsk2img
@ -8,16 +8,18 @@ TESTS = test-lzw
.PHONY: all tests strip clean format .PHONY: all tests strip clean format
all: $(BIN) all: $(BIN)
tests: $(TESTS) tests: $(TESTS)
strip: $(BIN) strip: $(BIN)
$(STRIP) $^ $(STRIP) $^
test-lzw: lzw.o utils.o test-lzw: lzw.o utils.o
dsk2img: lzw.o utils.o dsk2img: lzw.o utils.o
clean: clean:
$(RM) $(BIN) $(TESTS) *.o *~ *% $(RM) $(BIN) $(TESTS) *.o *.exe *~ *%
format: format:
$(FORMAT) *.c *.h $(FORMAT) *.c *.h

100
dsk2img.c
View File

@ -1,4 +1,4 @@
#define _POSIX_C_SOURCE 2 #define _POSIX_C_SOURCE 200809L
#include "lzw.h" #include "lzw.h"
#include "utils.h" #include "utils.h"
#include <stddef.h> #include <stddef.h>
@ -17,13 +17,22 @@
#if defined(__DOS__) || defined(__WINDOWS__) || defined(__NT__) || defined(__OS2__) #if defined(__DOS__) || defined(__WINDOWS__) || defined(__NT__) || defined(__OS2__)
#define DOSLIKE #define DOSLIKE
#define DIRSEP '\\' #define DIRSEP '\\'
#include <io.h> /* For _chsize() */
#else #else
#undef DOSLIKE #undef DOSLIKE
#define DIRSEP '/' #define DIRSEP '/'
#endif #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 READ_BUFFER_SIZE 4096
#define DECOMPRESS_BUFFER_SIZE 4096 #define DECOMPRESS_BUFFER_SIZE 4096
#define COPY_BUFFER_SIZE 8192
#endif
#pragma pack(1) #pragma pack(1)
struct dskheader { 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) void pad_file_to_size(FILE* f, unsigned long size)
{ {
long r; long current_pos;
unsigned long current_pos;
r = ftell(f); current_pos = ftell(f);
if (r < 0) { if (current_pos < 0) {
perror("ftell()"); perror("ftell()");
} }
current_pos = r; if ((unsigned long)current_pos > size)
if (current_pos > size) printf("ERROR: output file is larger than expected! (%ld vs %lu)\n", current_pos, size);
printf("ERROR: output file is larger than expected! (%lu vs %lu)\n", current_pos, size); else if ((unsigned long)current_pos != size) {
if (current_pos < size - 1) { #ifdef DOSLIKE
long pos; _chsize(fileno(f), (long)size);
#else
pos = ((long)size) - 1; ftruncate(fileno(f), size);
fseek(f, pos, SEEK_SET); #endif
} }
if (current_pos < size)
fputc(0, f);
} }
int valid_header(const struct dskheader* h) 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; unsigned long int copied_bytes;
size_t read_count, write_count; size_t read_count, write_count;
uint8_t* read_buffer = NULL; uint8_t* copy_buffer = NULL;
read_buffer = (uint8_t*)malloc(READ_BUFFER_SIZE); copy_buffer = (uint8_t*)malloc(COPY_BUFFER_SIZE);
if (read_buffer == NULL) { if (copy_buffer == NULL) {
perror("malloc()"); fputs("Can't allocate read buffer.", stderr);
return -1; return -1;
} }
for (copied_bytes = 0; copied_bytes < size;) { 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) { if (read_count == 0) {
perror("fread()"); perror("fread()");
free(read_buffer); free(copy_buffer);
return -2; return -2;
} }
update_checksum(checksum, read_buffer, read_count); update_checksum(checksum, copy_buffer, read_count);
write_count = fwrite(read_buffer, 1, read_count, fout); write_count = fwrite(copy_buffer, 1, read_count, fout);
if (read_count != write_count) { if (read_count != write_count) {
perror("fwrite()"); perror("fwrite()");
free(read_buffer); free(copy_buffer);
return -3; return -3;
} }
copied_bytes += read_count; copied_bytes += read_count;
} }
free(read_buffer); free(copy_buffer);
return 0; return 0;
} }
int copy_compressed_image_data(FILE* fin, FILE* fout) int copy_compressed_image_data(FILE* fin, FILE* fout)
{ {
size_t read_count, write_count; size_t read_count, write_count;
uint8_t* read_buffer = NULL; uint8_t* copy_buffer = NULL;
read_buffer = (uint8_t*)malloc(READ_BUFFER_SIZE); copy_buffer = (uint8_t*)malloc(COPY_BUFFER_SIZE);
if (read_buffer == NULL) { if (copy_buffer == NULL) {
perror("malloc()"); fputs("Can't allocate read buffer.", stderr);
return -1; return -1;
} }
for (;;) { 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) { if (read_count == 0) {
perror("fread()"); perror("fread()");
free(read_buffer); free(copy_buffer);
return -2; 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) { if (read_count != write_count) {
perror("fwrite()"); perror("fwrite()");
free(read_buffer); free(copy_buffer);
return -3; return -3;
} }
if (read_count < READ_BUFFER_SIZE) if (read_count < COPY_BUFFER_SIZE)
break; break;
} }
free(read_buffer); free(copy_buffer);
return 0; 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); read_buffer = (uint8_t*)malloc(READ_BUFFER_SIZE);
if (read_buffer == NULL) { if (read_buffer == NULL) {
perror("malloc()"); fputs("Can't allocate read buffer.", stderr);
return -1; return -1;
} }
decompress_buffer = (uint8_t*)malloc(DECOMPRESS_BUFFER_SIZE); decompress_buffer = (uint8_t*)malloc(DECOMPRESS_BUFFER_SIZE);
if (decompress_buffer == NULL) { if (decompress_buffer == NULL) {
perror("malloc()"); fputs("Can't allocate decompress buffer.", stderr);
free(read_buffer); free(read_buffer);
return -2; return -2;
} }
lzw = (struct lzw_ctx*)malloc(sizeof(struct lzw_ctx)); lzw = (struct lzw_ctx*)malloc(sizeof(struct lzw_ctx));
if (lzw == NULL) { if (lzw == NULL) {
perror("malloc()"); fputs("Can't allocate lzw_context.", stderr);
free(read_buffer); free(read_buffer);
free(decompress_buffer); free(decompress_buffer);
return -3; return -3;
@ -345,7 +351,6 @@ void dsk2img(const char* filename, int no_lzw)
long int start_offset; long int start_offset;
uint32_t checksum; uint32_t checksum;
int type_geom; int type_geom;
char *rbuf = NULL, *wbuf = NULL; /* for setvbuf() */
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Extracting %s\n", filename); fprintf(stderr, "Extracting %s\n", filename);
@ -355,12 +360,6 @@ void dsk2img(const char* filename, int no_lzw)
if (inf == NULL) if (inf == NULL)
return; 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); rres = fread(&header, sizeof(header), 1, inf);
if (rres != 1) { if (rres != 1) {
printf("Short read\n"); printf("Short read\n");
@ -427,12 +426,6 @@ void dsk2img(const char* filename, int no_lzw)
goto done; goto done;
} }
wbuf = (char*)malloc(4096);
if (wbuf)
setvbuf(outf, wbuf, _IOFBF, 4096);
else
printf("WARNING: can't allocate write buffer.");
checksum = 0; checksum = 0;
if (header.magic != MAGIC_DSK_COMPRESSED) { if (header.magic != MAGIC_DSK_COMPRESSED) {
if (copy_image_data(inf, outf, saved_size, &checksum) < 0) if (copy_image_data(inf, outf, saved_size, &checksum) < 0)
@ -440,7 +433,6 @@ void dsk2img(const char* filename, int no_lzw)
} else { } else {
if (no_lzw) { if (no_lzw) {
copy_compressed_image_data(inf, outf); copy_compressed_image_data(inf, outf);
goto done;
} else { } else {
if (decompress_image_data(inf, outf, saved_size, &checksum) < 0) if (decompress_image_data(inf, outf, saved_size, &checksum) < 0)
goto done; goto done;
@ -459,10 +451,6 @@ done:
fclose(inf); fclose(inf);
if (outname) if (outname)
free(outname); free(outname);
if (rbuf)
free(rbuf);
if (wbuf)
free(wbuf);
} }
void help(void) void help(void)