diff options
Diffstat (limited to 'tools/common.h')
-rw-r--r-- | tools/common.h | 96 |
1 files changed, 79 insertions, 17 deletions
diff --git a/tools/common.h b/tools/common.h index 4da0b2ef1..46b319919 100644 --- a/tools/common.h +++ b/tools/common.h @@ -1,40 +1,102 @@ #ifndef GUARD_COMMON_H #define GUARD_COMMON_H -int __getopt_long_i__; -#define getopt_long(c, v, s, l) getopt_long(c, v, s, l, &__getopt_long_i__) +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <inttypes.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <getopt.h> -FILE *fopen_verbose(char *filename, char *mode) { +int getopt_long_index; +#define getopt_long(c, v, s, l) getopt_long(c, v, s, l, &getopt_long_index) + +void *malloc_verbose(size_t size) { + void *m = malloc(size); + if (!m) { + fprintf(stderr, "Could not allocate %zu bytes: %s\n", size, strerror(errno)); + exit(1); + } + return m; +} + +FILE *fopen_verbose(const char *filename, char rw) { + char mode[3] = {rw, 'b', '\0'}; FILE *f = fopen(filename, mode); if (!f) { - fprintf(stderr, "Could not open file: \"%s\"\n", filename); + fprintf(stderr, "Could not open file \"%s\": %s\n", filename, strerror(errno)); + exit(1); } return f; } -uint8_t *read_u8(char *filename, int *size) { - FILE *f = fopen_verbose(filename, "rb"); - if (!f) { +void fread_verbose(uint8_t *data, size_t size, const char *filename, FILE *f) { + if (fread(data, 1, size, f) != size) { + fprintf(stderr, "Could not read from file \"%s\": %s\n", filename, strerror(errno)); + fclose(f); exit(1); } - fseek(f, 0, SEEK_END); - *size = ftell(f); - rewind(f); - uint8_t *data = malloc(*size); - if (*size != (int)fread(data, 1, *size, f)) { - fprintf(stderr, "Could not read file: \"%s\"\n", filename); +} + +void fwrite_verbose(const uint8_t *data, size_t size, const char *filename, FILE *f) { + if (fwrite(data, 1, size, f) != size) { + fprintf(stderr, "Could not write to file \"%s\": %s\n", filename, strerror(errno)); + fclose(f); exit(1); } +} + +long file_size(const char *filename, FILE *f) { + long size = 0; + if (!fseek(f, 0, SEEK_END)) { + size = ftell(f); + if (size != -1) { + rewind(f); + } + } + if (errno) { + fprintf(stderr, "Could not measure file \"%s\": %s\n", filename, strerror(errno)); + exit(1); + } + return size; +} + +uint8_t *read_u8(const char *filename, long *size) { + FILE *f = fopen_verbose(filename, 'r'); + *size = file_size(filename, f); + uint8_t *data = malloc_verbose(*size); + fread_verbose(data, *size, filename, f); fclose(f); return data; } -void write_u8(char *filename, uint8_t *data, int size) { - FILE *f = fopen_verbose(filename, "wb"); - if (f) { - fwrite(data, 1, size, f); +void write_u8(const char *filename, uint8_t *data, size_t size) { + FILE *f = fopen_verbose(filename, 'w'); + fwrite_verbose(data, size, filename, f); + fclose(f); +} + +uint32_t read_png_width_verbose(const char *filename) { + FILE *f = fopen_verbose(filename, 'r'); + uint8_t header[16] = {0}; + fread_verbose(header, sizeof(header), filename, f); + static uint8_t expected_header[16] = { + 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n', // signature + 0, 0, 0, 13, // IHDR chunk length + 'I', 'H', 'D', 'R', // IHDR chunk type + }; + if (memcmp(header, expected_header, sizeof(header))) { + fprintf(stderr, "Not a valid PNG file: \"%s\"\n", filename); fclose(f); + exit(1); } + uint8_t bytes[4] = {0}; + fread_verbose(bytes, sizeof(bytes), filename, f); + fclose(f); + return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; } #endif // GUARD_COMMON_H |