diff options
author | jvech <jmvalenciae@unal.edu.co> | 2023-06-18 15:03:25 -0500 |
---|---|---|
committer | jvech <jmvalenciae@unal.edu.co> | 2023-06-18 15:03:25 -0500 |
commit | 3113ade53d0dd889058c7838bb19c0fa0492b410 (patch) | |
tree | 4ca9353b421fbdc9d8ead8a257c415be133315d7 /src/ppm.c |
init: ppm library utilities implemented
It is not completed at all but it works well
Diffstat (limited to 'src/ppm.c')
-rw-r--r-- | src/ppm.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/ppm.c b/src/ppm.c new file mode 100644 index 0000000..f96e950 --- /dev/null +++ b/src/ppm.c @@ -0,0 +1,94 @@ +#include "ppm.h" + +static void read_header(FILE *fp, char ppm_type[2], int img_size[3]); +static void read_p6_data(FILE *fp, Image *img); + +void +ppm_write(const char *file, Image *img) +{ + FILE *fp = fopen(file, "w"); + + if (fp == NULL) { + perror("ppm_read() Error"); + exit(1); + } + + size_t n_pixels; + + fprintf(fp, "P6\n%d %d\n%d\n", img->width, img->height, img->pixel_bits); + fwrite(img->data, n_pixels, sizeof(uint8_t), fp); + fclose(fp); +} + +void +ppm_read(const char *file, Image *img) + /* + * Read a ppm image + */ +{ + FILE *fp = fopen(file, "r"); + + if (fp == NULL) { + perror("ppm_read() Error"); + exit(1); + } + + char ppm_type[3]; + int img_size[3]; + + read_header(fp, ppm_type, img_size); + img->width = img_size[0]; + img->height = img_size[1]; + img->pixel_bits = img_size[2]; + + if (!strcmp(ppm_type, "P6")) read_p6_data(fp, img); + else { + fprintf(stderr, "ppm_read() Error: %s format not supported\n", ppm_type); + fclose(fp); + exit(1); + } + fclose(fp); +} + +void +read_header(FILE *fp, char ppm_type[2], int img_size[3]) +{ + int i, n, ret; + char line_buffer[70], *buffer; + + buffer = fgets(line_buffer, 70, fp); + for (i = n = 0; i < 4; ) { + + if (i == 0) { + sscanf(line_buffer, "%2s%n", ppm_type, &n); + buffer += n; + i++; + } + + else if (i > 0) { + ret = sscanf(buffer, "%d%n", img_size + i - 1, &n); + if (ret >= 1) { + buffer += n; + i++; + } else buffer = fgets(line_buffer, 70, fp); + } + } +} + +void +read_p6_data(FILE *fp, Image *img) +{ + int n_pixels = img->width * img->height * 3; + img->data = calloc(n_pixels, sizeof(uint8_t)); + + if (img->data == NULL) { + perror("read_p6_data() Error"); + exit(1); + } + + fread(img->data, n_pixels, sizeof(uint8_t), fp); + if (ferror(fp)) { + perror("read_p6_data() Error"); + exit(1); + } +} |