aboutsummaryrefslogtreecommitdiff
path: root/src/ppm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ppm.c')
-rw-r--r--src/ppm.c94
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);
+ }
+}
Feel free to download, copy and edit any repo