aboutsummaryrefslogtreecommitdiff
path: root/src/ppm.c
blob: a868b76507720335a5cbe1c941680172e595a78b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#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)
{
    /*
     * Write a ppm file
     */
    FILE *fp;
    fp = (file) ? fopen(file, "r") : stdout;

    if (fp == NULL) {
        perror("ppm_read() Error");
        exit(1);
    }

    size_t n_pixels = img->width * img->height * 3;

    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);
    if (fp != stdout) fclose(fp);
}

void
ppm_read(const char *file, Image *img)
    /*
     * Read a ppm file
     */
{
    FILE *fp;
    fp = (file) ? fopen(file, "r") : stdin;

    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);
    }
    if (fp != stdin) 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