Blame


1 28994509 2004-04-21 devnull #include <u.h>
2 28994509 2004-04-21 devnull #include <libc.h>
3 28994509 2004-04-21 devnull #include <bio.h>
4 28994509 2004-04-21 devnull #include <draw.h>
5 28994509 2004-04-21 devnull #include <ctype.h>
6 28994509 2004-04-21 devnull #include "imagefile.h"
7 28994509 2004-04-21 devnull
8 28994509 2004-04-21 devnull Rawimage *readppm(Biobuf*, Rawimage*);
9 28994509 2004-04-21 devnull
10 28994509 2004-04-21 devnull /*
11 28994509 2004-04-21 devnull * fetch a non-comment character.
12 28994509 2004-04-21 devnull */
13 28994509 2004-04-21 devnull static
14 28994509 2004-04-21 devnull int
15 28994509 2004-04-21 devnull Bgetch(Biobuf *b)
16 28994509 2004-04-21 devnull {
17 28994509 2004-04-21 devnull int c;
18 28994509 2004-04-21 devnull
19 6b32f96d 2005-01-14 devnull c = Bgetc(b);
20 6b32f96d 2005-01-14 devnull if(c == '#') {
21 6b32f96d 2005-01-14 devnull while((c = Bgetc(b)) != Beof && c != '\n')
22 6b32f96d 2005-01-14 devnull ;
23 6b32f96d 2005-01-14 devnull }
24 6b32f96d 2005-01-14 devnull return c;
25 28994509 2004-04-21 devnull }
26 28994509 2004-04-21 devnull
27 28994509 2004-04-21 devnull /*
28 28994509 2004-04-21 devnull * fetch a nonnegative decimal integer.
29 28994509 2004-04-21 devnull */
30 28994509 2004-04-21 devnull static
31 28994509 2004-04-21 devnull int
32 28994509 2004-04-21 devnull Bgetint(Biobuf *b)
33 28994509 2004-04-21 devnull {
34 28994509 2004-04-21 devnull int c;
35 28994509 2004-04-21 devnull int i;
36 28994509 2004-04-21 devnull
37 28994509 2004-04-21 devnull while((c = Bgetch(b)) != Beof && !isdigit(c))
38 28994509 2004-04-21 devnull ;
39 28994509 2004-04-21 devnull if(c == Beof)
40 28994509 2004-04-21 devnull return -1;
41 28994509 2004-04-21 devnull
42 28994509 2004-04-21 devnull i = 0;
43 28994509 2004-04-21 devnull do {
44 28994509 2004-04-21 devnull i = i*10 + (c-'0');
45 28994509 2004-04-21 devnull } while((c = Bgetch(b)) != Beof && isdigit(c));
46 28994509 2004-04-21 devnull
47 28994509 2004-04-21 devnull return i;
48 28994509 2004-04-21 devnull }
49 28994509 2004-04-21 devnull
50 28994509 2004-04-21 devnull static
51 28994509 2004-04-21 devnull int
52 28994509 2004-04-21 devnull Bgetdecimalbit(Biobuf *b)
53 28994509 2004-04-21 devnull {
54 28994509 2004-04-21 devnull int c;
55 28994509 2004-04-21 devnull while((c = Bgetch(b)) != Beof && c != '0' && c != '1')
56 28994509 2004-04-21 devnull ;
57 28994509 2004-04-21 devnull if(c == Beof)
58 28994509 2004-04-21 devnull return -1;
59 28994509 2004-04-21 devnull return c == '1';
60 28994509 2004-04-21 devnull }
61 28994509 2004-04-21 devnull
62 28994509 2004-04-21 devnull static int bitc, nbit;
63 28994509 2004-04-21 devnull
64 28994509 2004-04-21 devnull static
65 28994509 2004-04-21 devnull int
66 28994509 2004-04-21 devnull Bgetbit(Biobuf *b)
67 28994509 2004-04-21 devnull {
68 28994509 2004-04-21 devnull if(nbit == 0) {
69 28994509 2004-04-21 devnull nbit = 8;
70 28994509 2004-04-21 devnull bitc = Bgetc(b);
71 28994509 2004-04-21 devnull if(bitc == -1)
72 28994509 2004-04-21 devnull return -1;
73 28994509 2004-04-21 devnull }
74 28994509 2004-04-21 devnull nbit--;
75 28994509 2004-04-21 devnull return (bitc >> (nbit-1)) & 0x1;
76 28994509 2004-04-21 devnull }
77 28994509 2004-04-21 devnull
78 28994509 2004-04-21 devnull static
79 28994509 2004-04-21 devnull void
80 28994509 2004-04-21 devnull Bflushbit(Biobuf *b)
81 28994509 2004-04-21 devnull {
82 28994509 2004-04-21 devnull USED(b);
83 28994509 2004-04-21 devnull nbit = 0;
84 28994509 2004-04-21 devnull }
85 28994509 2004-04-21 devnull
86 28994509 2004-04-21 devnull
87 28994509 2004-04-21 devnull Rawimage**
88 28994509 2004-04-21 devnull readpixmap(int fd, int colorspace)
89 28994509 2004-04-21 devnull {
90 28994509 2004-04-21 devnull Rawimage **array, *a;
91 28994509 2004-04-21 devnull Biobuf b;
92 28994509 2004-04-21 devnull char buf[ERRMAX];
93 28994509 2004-04-21 devnull int i;
94 28994509 2004-04-21 devnull char *e;
95 28994509 2004-04-21 devnull
96 28994509 2004-04-21 devnull USED(colorspace);
97 28994509 2004-04-21 devnull if(Binit(&b, fd, OREAD) < 0)
98 28994509 2004-04-21 devnull return nil;
99 28994509 2004-04-21 devnull
100 28994509 2004-04-21 devnull werrstr("");
101 28994509 2004-04-21 devnull e = "out of memory";
102 28994509 2004-04-21 devnull if((array = malloc(sizeof *array)) == nil)
103 28994509 2004-04-21 devnull goto Error;
104 28994509 2004-04-21 devnull if((array[0] = malloc(sizeof *array[0])) == nil)
105 28994509 2004-04-21 devnull goto Error;
106 28994509 2004-04-21 devnull memset(array[0], 0, sizeof *array[0]);
107 28994509 2004-04-21 devnull
108 28994509 2004-04-21 devnull for(i=0; i<3; i++)
109 28994509 2004-04-21 devnull array[0]->chans[i] = nil;
110 28994509 2004-04-21 devnull
111 28994509 2004-04-21 devnull e = "bad file format";
112 28994509 2004-04-21 devnull switch(Bgetc(&b)) {
113 28994509 2004-04-21 devnull case 'P':
114 28994509 2004-04-21 devnull Bungetc(&b);
115 28994509 2004-04-21 devnull a = readppm(&b, array[0]);
116 28994509 2004-04-21 devnull break;
117 28994509 2004-04-21 devnull default:
118 28994509 2004-04-21 devnull a = nil;
119 28994509 2004-04-21 devnull break;
120 28994509 2004-04-21 devnull }
121 28994509 2004-04-21 devnull if(a == nil)
122 28994509 2004-04-21 devnull goto Error;
123 28994509 2004-04-21 devnull array[0] = a;
124 28994509 2004-04-21 devnull
125 28994509 2004-04-21 devnull return array;
126 28994509 2004-04-21 devnull
127 28994509 2004-04-21 devnull Error:
128 28994509 2004-04-21 devnull if(array)
129 28994509 2004-04-21 devnull free(array[0]);
130 28994509 2004-04-21 devnull free(array);
131 28994509 2004-04-21 devnull
132 28994509 2004-04-21 devnull errstr(buf, sizeof buf);
133 28994509 2004-04-21 devnull if(buf[0] == 0)
134 28994509 2004-04-21 devnull strcpy(buf, e);
135 28994509 2004-04-21 devnull errstr(buf, sizeof buf);
136 28994509 2004-04-21 devnull
137 28994509 2004-04-21 devnull return nil;
138 28994509 2004-04-21 devnull }
139 28994509 2004-04-21 devnull
140 28994509 2004-04-21 devnull typedef struct Pix Pix;
141 28994509 2004-04-21 devnull struct Pix {
142 28994509 2004-04-21 devnull char magic;
143 28994509 2004-04-21 devnull int maxcol;
144 28994509 2004-04-21 devnull int (*fetch)(Biobuf*);
145 28994509 2004-04-21 devnull int nchan;
146 28994509 2004-04-21 devnull int chandesc;
147 28994509 2004-04-21 devnull int invert;
148 28994509 2004-04-21 devnull void (*flush)(Biobuf*);
149 28994509 2004-04-21 devnull };
150 28994509 2004-04-21 devnull
151 28994509 2004-04-21 devnull static Pix pix[] = {
152 840bb968 2004-04-25 devnull { '1', 1, Bgetdecimalbit, 1, CY, 1, 0 }, /* portable bitmap */
153 28994509 2004-04-21 devnull { '4', 1, Bgetbit, 1, CY, 1, Bflushbit }, /* raw portable bitmap */
154 840bb968 2004-04-25 devnull { '2', 0, Bgetint, 1, CY, 0, 0 }, /* portable greymap */
155 840bb968 2004-04-25 devnull { '5', 0, Bgetc, 1, CY, 0, 0 }, /* raw portable greymap */
156 840bb968 2004-04-25 devnull { '3', 0, Bgetint, 3, CRGB, 0, 0 }, /* portable pixmap */
157 840bb968 2004-04-25 devnull { '6', 0, Bgetc, 3, CRGB, 0, 0 }, /* raw portable pixmap */
158 cbeb0b26 2006-04-01 devnull { 0 }
159 28994509 2004-04-21 devnull };
160 28994509 2004-04-21 devnull
161 28994509 2004-04-21 devnull Rawimage*
162 28994509 2004-04-21 devnull readppm(Biobuf *b, Rawimage *a)
163 28994509 2004-04-21 devnull {
164 28994509 2004-04-21 devnull int i, ch, wid, ht, r, c;
165 28994509 2004-04-21 devnull int maxcol, nchan, invert;
166 28994509 2004-04-21 devnull int (*fetch)(Biobuf*);
167 28994509 2004-04-21 devnull uchar *rgb[3];
168 28994509 2004-04-21 devnull char buf[ERRMAX];
169 28994509 2004-04-21 devnull char *e;
170 28994509 2004-04-21 devnull Pix *p;
171 28994509 2004-04-21 devnull
172 28994509 2004-04-21 devnull e = "bad file format";
173 28994509 2004-04-21 devnull if(Bgetc(b) != 'P')
174 28994509 2004-04-21 devnull goto Error;
175 28994509 2004-04-21 devnull
176 28994509 2004-04-21 devnull c = Bgetc(b);
177 28994509 2004-04-21 devnull for(p=pix; p->magic; p++)
178 28994509 2004-04-21 devnull if(p->magic == c)
179 28994509 2004-04-21 devnull break;
180 28994509 2004-04-21 devnull if(p->magic == 0)
181 28994509 2004-04-21 devnull goto Error;
182 28994509 2004-04-21 devnull
183 28994509 2004-04-21 devnull
184 28994509 2004-04-21 devnull wid = Bgetint(b);
185 28994509 2004-04-21 devnull ht = Bgetint(b);
186 28994509 2004-04-21 devnull if(wid <= 0 || ht <= 0)
187 28994509 2004-04-21 devnull goto Error;
188 28994509 2004-04-21 devnull a->r = Rect(0,0,wid,ht);
189 28994509 2004-04-21 devnull
190 28994509 2004-04-21 devnull maxcol = p->maxcol;
191 28994509 2004-04-21 devnull if(maxcol == 0) {
192 28994509 2004-04-21 devnull maxcol = Bgetint(b);
193 28994509 2004-04-21 devnull if(maxcol <= 0)
194 28994509 2004-04-21 devnull goto Error;
195 28994509 2004-04-21 devnull }
196 28994509 2004-04-21 devnull
197 28994509 2004-04-21 devnull e = "out of memory";
198 28994509 2004-04-21 devnull for(i=0; i<p->nchan; i++)
199 28994509 2004-04-21 devnull if((rgb[i] = a->chans[i] = malloc(wid*ht)) == nil)
200 28994509 2004-04-21 devnull goto Error;
201 28994509 2004-04-21 devnull a->nchans = p->nchan;
202 28994509 2004-04-21 devnull a->chanlen = wid*ht;
203 28994509 2004-04-21 devnull a->chandesc = p->chandesc;
204 28994509 2004-04-21 devnull
205 28994509 2004-04-21 devnull e = "error reading file";
206 28994509 2004-04-21 devnull
207 28994509 2004-04-21 devnull fetch = p->fetch;
208 28994509 2004-04-21 devnull nchan = p->nchan;
209 28994509 2004-04-21 devnull invert = p->invert;
210 28994509 2004-04-21 devnull for(r=0; r<ht; r++) {
211 28994509 2004-04-21 devnull for(c=0; c<wid; c++) {
212 28994509 2004-04-21 devnull for(i=0; i<nchan; i++) {
213 28994509 2004-04-21 devnull if((ch = (*fetch)(b)) < 0)
214 28994509 2004-04-21 devnull goto Error;
215 28994509 2004-04-21 devnull if(invert)
216 28994509 2004-04-21 devnull ch = maxcol - ch;
217 28994509 2004-04-21 devnull *rgb[i]++ = (ch * 255)/maxcol;
218 28994509 2004-04-21 devnull }
219 28994509 2004-04-21 devnull }
220 28994509 2004-04-21 devnull if(p->flush)
221 28994509 2004-04-21 devnull (*p->flush)(b);
222 28994509 2004-04-21 devnull }
223 28994509 2004-04-21 devnull
224 28994509 2004-04-21 devnull return a;
225 28994509 2004-04-21 devnull
226 28994509 2004-04-21 devnull Error:
227 28994509 2004-04-21 devnull errstr(buf, sizeof buf);
228 28994509 2004-04-21 devnull if(buf[0] == 0)
229 28994509 2004-04-21 devnull strcpy(buf, e);
230 28994509 2004-04-21 devnull errstr(buf, sizeof buf);
231 28994509 2004-04-21 devnull
232 28994509 2004-04-21 devnull for(i=0; i<3; i++)
233 28994509 2004-04-21 devnull free(a->chans[i]);
234 28994509 2004-04-21 devnull free(a->cmap);
235 28994509 2004-04-21 devnull return nil;
236 28994509 2004-04-21 devnull }