aboutsummaryrefslogtreecommitdiffstats
path: root/rd/read-ppm.c
blob: 210e4c33b68261bea04f28236dee0589d7854a53 (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "readers.h"

/* ---------------------------------------------------------------------- */
/* load                                                                   */

struct ppm_state {
    FILE          *infile;
    int           width,height;
    unsigned char *row;
};

static void*
pnm_init(FILE *fp, char *filename, unsigned int page,
	 struct ida_image_info *i, int thumbnail)
{
    struct ppm_state *h;
    char line[1024];
    char p;

    h = malloc(sizeof(*h));
    memset(h,0,sizeof(*h));

    h->infile = fp;
    fgets(line,sizeof(line),fp); /* P[456] */
    p = line[1];
    fgets(line,sizeof(line),fp); /* width height */
    while ('#' == line[0])
	fgets(line,sizeof(line),fp); /* skip comments */
    sscanf(line,"%d %d",&h->width,&h->height);
    if (p != '4')
	fgets(line,sizeof(line),fp); /* depth ??? */
    if (0 == h->width || 0 == h->height)
	goto oops;
    i->width  = h->width;
    i->height = h->height;
    i->npages = 1;
    h->row = malloc(h->width*3);

    return h;

 oops:
    fclose(fp);
    free(h);
    return NULL;
}

static void
ppm_read(unsigned char *dst, unsigned int line, void *data)
{
    struct ppm_state *h = data;

    fread(dst,h->width,3,h->infile);
}

static void
pgm_read(unsigned char *dst, unsigned int line, void *data)
{
    struct ppm_state *h = data;
    unsigned char *src;
    int x;

    fread(h->row,h->width,1,h->infile);
    src = h->row;
    for (x = 0; x < h->width; x++) {
	dst[0] = src[0];
	dst[1] = src[0];
	dst[2] = src[0];
	dst += 3;
	src += 1;
    }
}

static void
pbm_read(unsigned char *dst, unsigned int line, void *data)
{
    struct ppm_state *h = data;
    int bpl;

    bpl = ((h->width+7) >> 3);
    fread(h->row,bpl,1,h->infile);
    load_bits_msb(dst,(unsigned char*)(h->row),h->width,255,0);
}

static void
pnm_done(void *data)
{
    struct ppm_state *h = data;

    fclose(h->infile);
    free(h->row);
    free(h);
}

struct ida_loader ppm_loader = {
    magic: "P6",
    moff:  0,
    mlen:  2,
    name:  "ppm parser",
    init:  pnm_init,
    read:  ppm_read,
    done:  pnm_done,
};

static struct ida_loader pgm_loader = {
    magic: "P5",
    moff:  0,
    mlen:  2,
    name:  "pgm parser",
    init:  pnm_init,
    read:  pgm_read,
    done:  pnm_done,
};

static struct ida_loader pbm_loader = {
    magic: "P4",
    moff:  0,
    mlen:  2,
    name:  "pbm parser",
    init:  pnm_init,
    read:  pbm_read,
    done:  pnm_done,
};

static void __init init_rd(void)
{
    load_register(&ppm_loader);
    load_register(&pgm_loader);
    load_register(&pbm_loader);
}