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 |
init: ppm library utilities implemented
It is not completed at all but it works well
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 16 | ||||
-rw-r--r-- | src/ppm.c | 94 | ||||
-rw-r--r-- | src/ppm.h | 15 |
3 files changed, 125 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..242e464 --- /dev/null +++ b/src/main.c @@ -0,0 +1,16 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "ppm.h" + +int main(int argc, char *argv[]) +{ + Image img; + ppm_read("images/boxes_1.ppm", &img); + + printf("width: %d\n", img.width); + printf("height: %d\n", img.height); + printf("bits: %d\n", img.pixel_bits); + printf("data[2]: %d\n", img.data[2]); + return 0; +} 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); + } +} diff --git a/src/ppm.h b/src/ppm.h new file mode 100644 index 0000000..5cf8b02 --- /dev/null +++ b/src/ppm.h @@ -0,0 +1,15 @@ +#ifndef __PPM__ +#define __PPM__ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +typedef struct Image { + uint8_t *data; + int32_t width, height, pixel_bits; +} Image; + +void ppm_read(const char *file, Image *img); +void ppm_write(const char *file, Image *img); +#endif |