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 <ctype.h>
4 28994509 2004-04-21 devnull #include <bio.h>
5 28994509 2004-04-21 devnull #include <flate.h>
6 28994509 2004-04-21 devnull #include <draw.h>
7 28994509 2004-04-21 devnull #include "imagefile.h"
8 28994509 2004-04-21 devnull
9 28994509 2004-04-21 devnull int debug;
10 28994509 2004-04-21 devnull
11 28994509 2004-04-21 devnull enum{ IDATSIZE=1000000,
12 28994509 2004-04-21 devnull /* filtering algorithms, supposedly increase compression */
13 28994509 2004-04-21 devnull FilterNone = 0, /* new[x][y] = buf[x][y] */
14 fa325e9b 2020-01-10 cross FilterSub = 1, /* new[x][y] = buf[x][y] + new[x-1][y] */
15 fa325e9b 2020-01-10 cross FilterUp = 2, /* new[x][y] = buf[x][y] + new[x][y-1] */
16 fa325e9b 2020-01-10 cross FilterAvg = 3, /* new[x][y] = buf[x][y] + (new[x-1][y]+new[x][y-1])/2 */
17 6a8f21b2 2005-03-18 devnull FilterPaeth= 4, /* new[x][y] = buf[x][y] + paeth(new[x-1][y],new[x][y-1],new[x-1][y-1]) */
18 28994509 2004-04-21 devnull FilterLast = 5,
19 cbeb0b26 2006-04-01 devnull PropertyBit = 1<<5
20 28994509 2004-04-21 devnull };
21 28994509 2004-04-21 devnull
22 6a8f21b2 2005-03-18 devnull
23 6a8f21b2 2005-03-18 devnull typedef struct ZlibW{
24 cbeb0b26 2006-04-01 devnull uchar *chan[4]; /* Rawimage channels */
25 cbeb0b26 2006-04-01 devnull uchar *scan; /* new scanline */
26 cbeb0b26 2006-04-01 devnull uchar *pscan; /* previous scanline */
27 cbeb0b26 2006-04-01 devnull int scanl; /* scan len */
28 cbeb0b26 2006-04-01 devnull int scanp; /* scan pos */
29 cbeb0b26 2006-04-01 devnull int nchan; /* number of input chans */
30 cbeb0b26 2006-04-01 devnull int npix; /* pixels read so far */
31 cbeb0b26 2006-04-01 devnull int chanl; /* number of bytes allocated to chan[x] */
32 cbeb0b26 2006-04-01 devnull int scanpix;
33 cbeb0b26 2006-04-01 devnull int bpp; /* bits per sample */
34 6a8f21b2 2005-03-18 devnull int palsize;
35 cbeb0b26 2006-04-01 devnull int row; /* current scanline number */
36 6a8f21b2 2005-03-18 devnull uchar palette[3*256];
37 6a8f21b2 2005-03-18 devnull } ZlibW;
38 6a8f21b2 2005-03-18 devnull
39 28994509 2004-04-21 devnull typedef struct ZlibR{
40 28994509 2004-04-21 devnull Biobuf *bi;
41 28994509 2004-04-21 devnull uchar *buf;
42 cbeb0b26 2006-04-01 devnull uchar *b; /* next byte to decompress */
43 cbeb0b26 2006-04-01 devnull uchar *e; /* past end of buf */
44 6a8f21b2 2005-03-18 devnull ZlibW *w;
45 28994509 2004-04-21 devnull } ZlibR;
46 28994509 2004-04-21 devnull
47 9a054520 2010-02-08 rsc static uint32 *crctab;
48 28994509 2004-04-21 devnull static uchar PNGmagic[] = {137,80,78,71,13,10,26,10};
49 28994509 2004-04-21 devnull static char memerr[] = "ReadPNG: malloc failed: %r";
50 28994509 2004-04-21 devnull
51 9a054520 2010-02-08 rsc static uint32
52 28994509 2004-04-21 devnull get4(uchar *a)
53 28994509 2004-04-21 devnull {
54 28994509 2004-04-21 devnull return (a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3];
55 28994509 2004-04-21 devnull }
56 28994509 2004-04-21 devnull
57 28994509 2004-04-21 devnull static
58 28994509 2004-04-21 devnull void
59 28994509 2004-04-21 devnull pnginit(void)
60 28994509 2004-04-21 devnull {
61 28994509 2004-04-21 devnull static int inited;
62 28994509 2004-04-21 devnull
63 28994509 2004-04-21 devnull if(inited)
64 28994509 2004-04-21 devnull return;
65 28994509 2004-04-21 devnull inited = 1;
66 28994509 2004-04-21 devnull crctab = mkcrctab(0xedb88320);
67 28994509 2004-04-21 devnull if(crctab == nil)
68 28994509 2004-04-21 devnull sysfatal("mkcrctab error");
69 28994509 2004-04-21 devnull inflateinit();
70 28994509 2004-04-21 devnull }
71 28994509 2004-04-21 devnull
72 28994509 2004-04-21 devnull static
73 28994509 2004-04-21 devnull void*
74 28994509 2004-04-21 devnull pngmalloc(ulong n, int clear)
75 28994509 2004-04-21 devnull {
76 28994509 2004-04-21 devnull void *p;
77 28994509 2004-04-21 devnull
78 28994509 2004-04-21 devnull p = malloc(n);
79 28994509 2004-04-21 devnull if(p == nil)
80 28994509 2004-04-21 devnull sysfatal(memerr);
81 28994509 2004-04-21 devnull if(clear)
82 28994509 2004-04-21 devnull memset(p, 0, n);
83 28994509 2004-04-21 devnull return p;
84 28994509 2004-04-21 devnull }
85 28994509 2004-04-21 devnull
86 28994509 2004-04-21 devnull static int
87 28994509 2004-04-21 devnull getchunk(Biobuf *b, char *type, uchar *d, int m)
88 28994509 2004-04-21 devnull {
89 28994509 2004-04-21 devnull uchar buf[8];
90 9a054520 2010-02-08 rsc uint32 crc = 0, crc2;
91 28994509 2004-04-21 devnull int n, nr;
92 28994509 2004-04-21 devnull
93 28994509 2004-04-21 devnull if(Bread(b, buf, 8) != 8)
94 28994509 2004-04-21 devnull return -1;
95 28994509 2004-04-21 devnull n = get4(buf);
96 28994509 2004-04-21 devnull memmove(type, buf+4, 4);
97 28994509 2004-04-21 devnull type[4] = 0;
98 28994509 2004-04-21 devnull if(n > m)
99 28994509 2004-04-21 devnull sysfatal("getchunk needed %d, had %d", n, m);
100 28994509 2004-04-21 devnull nr = Bread(b, d, n);
101 28994509 2004-04-21 devnull if(nr != n)
102 28994509 2004-04-21 devnull sysfatal("getchunk read %d, expected %d", nr, n);
103 28994509 2004-04-21 devnull crc = blockcrc(crctab, crc, type, 4);
104 28994509 2004-04-21 devnull crc = blockcrc(crctab, crc, d, n);
105 28994509 2004-04-21 devnull if(Bread(b, buf, 4) != 4)
106 28994509 2004-04-21 devnull sysfatal("getchunk tlr failed");
107 28994509 2004-04-21 devnull crc2 = get4(buf);
108 28994509 2004-04-21 devnull if(crc != crc2)
109 28994509 2004-04-21 devnull sysfatal("getchunk crc failed");
110 28994509 2004-04-21 devnull return n;
111 28994509 2004-04-21 devnull }
112 28994509 2004-04-21 devnull
113 28994509 2004-04-21 devnull static int
114 28994509 2004-04-21 devnull zread(void *va)
115 28994509 2004-04-21 devnull {
116 28994509 2004-04-21 devnull ZlibR *z = va;
117 28994509 2004-04-21 devnull char type[5];
118 28994509 2004-04-21 devnull int n;
119 28994509 2004-04-21 devnull
120 28994509 2004-04-21 devnull if(z->b >= z->e){
121 28994509 2004-04-21 devnull refill_buffer:
122 28994509 2004-04-21 devnull z->b = z->buf;
123 28994509 2004-04-21 devnull n = getchunk(z->bi, type, z->b, IDATSIZE);
124 28994509 2004-04-21 devnull if(n < 0 || strcmp(type, "IEND") == 0)
125 28994509 2004-04-21 devnull return -1;
126 28994509 2004-04-21 devnull z->e = z->b + n;
127 6a8f21b2 2005-03-18 devnull if(!strcmp(type,"PLTE")) {
128 6a8f21b2 2005-03-18 devnull if (n < 3 || n > 3*256 || n%3)
129 6a8f21b2 2005-03-18 devnull sysfatal("invalid PLTE chunk len %d", n);
130 6a8f21b2 2005-03-18 devnull memcpy(z->w->palette, z->b, n);
131 6a8f21b2 2005-03-18 devnull z->w->palsize = n/3;
132 6a8f21b2 2005-03-18 devnull goto refill_buffer;
133 6a8f21b2 2005-03-18 devnull }
134 28994509 2004-04-21 devnull if(type[0] & PropertyBit)
135 28994509 2004-04-21 devnull goto refill_buffer; /* skip auxiliary chunks for now */
136 6a8f21b2 2005-03-18 devnull if(strcmp(type,"IDAT")) {
137 28994509 2004-04-21 devnull sysfatal("unrecognized mandatory chunk %s", type);
138 6a8f21b2 2005-03-18 devnull goto refill_buffer;
139 6a8f21b2 2005-03-18 devnull }
140 28994509 2004-04-21 devnull }
141 28994509 2004-04-21 devnull return *z->b++;
142 28994509 2004-04-21 devnull }
143 28994509 2004-04-21 devnull
144 fa325e9b 2020-01-10 cross static uchar
145 28994509 2004-04-21 devnull paeth(uchar a, uchar b, uchar c)
146 28994509 2004-04-21 devnull {
147 28994509 2004-04-21 devnull int p, pa, pb, pc;
148 fa325e9b 2020-01-10 cross
149 28994509 2004-04-21 devnull p = (int)a + (int)b - (int)c;
150 28994509 2004-04-21 devnull pa = abs(p - (int)a);
151 28994509 2004-04-21 devnull pb = abs(p - (int)b);
152 28994509 2004-04-21 devnull pc = abs(p - (int)c);
153 28994509 2004-04-21 devnull
154 28994509 2004-04-21 devnull if(pa <= pb && pa <= pc)
155 28994509 2004-04-21 devnull return a;
156 28994509 2004-04-21 devnull else if(pb <= pc)
157 28994509 2004-04-21 devnull return b;
158 28994509 2004-04-21 devnull return c;
159 28994509 2004-04-21 devnull }
160 28994509 2004-04-21 devnull
161 28994509 2004-04-21 devnull static void
162 6a8f21b2 2005-03-18 devnull unfilter(int alg, uchar *buf, uchar *up, int len, int bypp)
163 28994509 2004-04-21 devnull {
164 6a8f21b2 2005-03-18 devnull int i;
165 28994509 2004-04-21 devnull switch(alg){
166 6a8f21b2 2005-03-18 devnull case FilterNone:
167 6a8f21b2 2005-03-18 devnull break;
168 6a8f21b2 2005-03-18 devnull
169 28994509 2004-04-21 devnull case FilterSub:
170 6a8f21b2 2005-03-18 devnull for (i = bypp; i < len; ++i)
171 6a8f21b2 2005-03-18 devnull buf[i] += buf[i-bypp];
172 28994509 2004-04-21 devnull break;
173 6a8f21b2 2005-03-18 devnull
174 28994509 2004-04-21 devnull case FilterUp:
175 6a8f21b2 2005-03-18 devnull for (i = 0; i < len; ++i)
176 6a8f21b2 2005-03-18 devnull buf[i] += up[i];
177 28994509 2004-04-21 devnull break;
178 6a8f21b2 2005-03-18 devnull
179 28994509 2004-04-21 devnull case FilterAvg:
180 6a8f21b2 2005-03-18 devnull for (i = 0; i < bypp; ++i)
181 6a8f21b2 2005-03-18 devnull buf[i] += (0+up[i])/2;
182 6a8f21b2 2005-03-18 devnull for (; i < len; ++i)
183 6a8f21b2 2005-03-18 devnull buf[i] += (buf[i-bypp]+up[i])/2;
184 28994509 2004-04-21 devnull break;
185 6a8f21b2 2005-03-18 devnull
186 28994509 2004-04-21 devnull case FilterPaeth:
187 6a8f21b2 2005-03-18 devnull for (i = 0; i < bypp; ++i)
188 6a8f21b2 2005-03-18 devnull buf[i] += paeth(0, up[i], 0);
189 6a8f21b2 2005-03-18 devnull for (; i < len; ++i)
190 6a8f21b2 2005-03-18 devnull buf[i] += paeth(buf[i-bypp], up[i], up[i-bypp]);
191 28994509 2004-04-21 devnull break;
192 6a8f21b2 2005-03-18 devnull default:
193 6a8f21b2 2005-03-18 devnull sysfatal("unknown filtering scheme %d\n", alg);
194 28994509 2004-04-21 devnull }
195 6a8f21b2 2005-03-18 devnull }
196 6a8f21b2 2005-03-18 devnull
197 6a8f21b2 2005-03-18 devnull static void
198 6a8f21b2 2005-03-18 devnull convertpix(ZlibW *z, uchar *pixel, uchar *r, uchar *g, uchar *b)
199 6a8f21b2 2005-03-18 devnull {
200 6a8f21b2 2005-03-18 devnull int off;
201 6a8f21b2 2005-03-18 devnull switch (z->nchan) {
202 6a8f21b2 2005-03-18 devnull case 1: /* gray or indexed */
203 6a8f21b2 2005-03-18 devnull case 2: /* gray+alpha */
204 6a8f21b2 2005-03-18 devnull if (z->bpp < 8)
205 6a8f21b2 2005-03-18 devnull pixel[0] >>= 8-z->bpp;
206 6a8f21b2 2005-03-18 devnull if (pixel[0] > z->palsize)
207 6a8f21b2 2005-03-18 devnull sysfatal("index %d out of bounds %d", pixel[0], z->palsize);
208 6a8f21b2 2005-03-18 devnull off = 3*pixel[0];
209 6a8f21b2 2005-03-18 devnull *r = z->palette[off];
210 6a8f21b2 2005-03-18 devnull *g = z->palette[off+1];
211 6a8f21b2 2005-03-18 devnull *b = z->palette[off+2];
212 6a8f21b2 2005-03-18 devnull break;
213 6a8f21b2 2005-03-18 devnull case 3: /* rgb */
214 6a8f21b2 2005-03-18 devnull case 4: /* rgb+alpha */
215 6a8f21b2 2005-03-18 devnull *r = pixel[0];
216 6a8f21b2 2005-03-18 devnull *g = pixel[1];
217 6a8f21b2 2005-03-18 devnull *b = pixel[2];
218 6a8f21b2 2005-03-18 devnull break;
219 6a8f21b2 2005-03-18 devnull default:
220 6a8f21b2 2005-03-18 devnull sysfatal("bad number of channels: %d", z->nchan);
221 fa325e9b 2020-01-10 cross }
222 6a8f21b2 2005-03-18 devnull }
223 6a8f21b2 2005-03-18 devnull
224 6a8f21b2 2005-03-18 devnull static void
225 6a8f21b2 2005-03-18 devnull scan(ZlibW *z)
226 6a8f21b2 2005-03-18 devnull {
227 6a8f21b2 2005-03-18 devnull uchar *p;
228 6a8f21b2 2005-03-18 devnull int i, bit, n, ch, nch, pd;
229 6a8f21b2 2005-03-18 devnull uchar cb;
230 6a8f21b2 2005-03-18 devnull uchar pixel[4];
231 6a8f21b2 2005-03-18 devnull
232 6a8f21b2 2005-03-18 devnull p = z->scan;
233 6a8f21b2 2005-03-18 devnull nch = z->nchan;
234 6a8f21b2 2005-03-18 devnull
235 6a8f21b2 2005-03-18 devnull unfilter(p[0], p+1, z->pscan+1, z->scanl-1, (nch*z->bpp+7)/8);
236 6a8f21b2 2005-03-18 devnull /*
237 fa325e9b 2020-01-10 cross * Adam7 interlace order.
238 6a8f21b2 2005-03-18 devnull * 1 6 4 6 2 6 4 6
239 6a8f21b2 2005-03-18 devnull * 7 7 7 7 7 7 7 7
240 6a8f21b2 2005-03-18 devnull * 5 6 5 6 5 6 5 6
241 6a8f21b2 2005-03-18 devnull * 7 7 7 7 7 7 7 7
242 6a8f21b2 2005-03-18 devnull * 3 6 4 6 3 6 4 6
243 6a8f21b2 2005-03-18 devnull * 7 7 7 7 7 7 7 7
244 6a8f21b2 2005-03-18 devnull * 5 6 5 6 5 6 5 6
245 6a8f21b2 2005-03-18 devnull * 7 7 7 7 7 7 7 7
246 6a8f21b2 2005-03-18 devnull */
247 6a8f21b2 2005-03-18 devnull ch = 0;
248 6a8f21b2 2005-03-18 devnull n = 0;
249 6a8f21b2 2005-03-18 devnull cb = 128;
250 6a8f21b2 2005-03-18 devnull pd = z->row * z->scanpix;
251 6a8f21b2 2005-03-18 devnull for (i = 1; i < z->scanl; ++i)
252 6a8f21b2 2005-03-18 devnull for (bit = 128; bit > 0; bit /= 2) {
253 6a8f21b2 2005-03-18 devnull
254 6a8f21b2 2005-03-18 devnull pixel[ch] &= ~cb;
255 6a8f21b2 2005-03-18 devnull if (p[i] & bit)
256 6a8f21b2 2005-03-18 devnull pixel[ch] |= cb;
257 6a8f21b2 2005-03-18 devnull
258 6a8f21b2 2005-03-18 devnull cb >>= 1;
259 6a8f21b2 2005-03-18 devnull
260 6a8f21b2 2005-03-18 devnull if (++n == z->bpp) {
261 6a8f21b2 2005-03-18 devnull cb = 128;
262 6a8f21b2 2005-03-18 devnull n = 0;
263 6a8f21b2 2005-03-18 devnull ch++;
264 6a8f21b2 2005-03-18 devnull }
265 6a8f21b2 2005-03-18 devnull if (ch == nch) {
266 6a8f21b2 2005-03-18 devnull if (z->npix++ < z->chanl)
267 6a8f21b2 2005-03-18 devnull convertpix(z,pixel,z->chan[0]+pd,z->chan[1]+pd,z->chan[2]+pd);
268 6a8f21b2 2005-03-18 devnull pd++;
269 6a8f21b2 2005-03-18 devnull if (pd % z->scanpix == 0)
270 6a8f21b2 2005-03-18 devnull goto out;
271 6a8f21b2 2005-03-18 devnull ch = 0;
272 6a8f21b2 2005-03-18 devnull }
273 6a8f21b2 2005-03-18 devnull }
274 6a8f21b2 2005-03-18 devnull out: ;
275 28994509 2004-04-21 devnull }
276 28994509 2004-04-21 devnull
277 28994509 2004-04-21 devnull static int
278 28994509 2004-04-21 devnull zwrite(void *va, void *vb, int n)
279 28994509 2004-04-21 devnull {
280 28994509 2004-04-21 devnull ZlibW *z = va;
281 28994509 2004-04-21 devnull uchar *buf = vb;
282 6a8f21b2 2005-03-18 devnull int i, j;
283 6a8f21b2 2005-03-18 devnull
284 6a8f21b2 2005-03-18 devnull j = z->scanp;
285 6a8f21b2 2005-03-18 devnull for (i = 0; i < n; ++i) {
286 6a8f21b2 2005-03-18 devnull z->scan[j++] = buf[i];
287 6a8f21b2 2005-03-18 devnull if (j == z->scanl) {
288 6a8f21b2 2005-03-18 devnull uchar *tp;
289 6a8f21b2 2005-03-18 devnull scan(z);
290 6a8f21b2 2005-03-18 devnull
291 6a8f21b2 2005-03-18 devnull tp = z->scan;
292 6a8f21b2 2005-03-18 devnull z->scan = z->pscan;
293 6a8f21b2 2005-03-18 devnull z->pscan = tp;
294 6a8f21b2 2005-03-18 devnull z->row++;
295 6a8f21b2 2005-03-18 devnull j = 0;
296 28994509 2004-04-21 devnull }
297 28994509 2004-04-21 devnull }
298 6a8f21b2 2005-03-18 devnull z->scanp = j;
299 6a8f21b2 2005-03-18 devnull
300 28994509 2004-04-21 devnull return n;
301 28994509 2004-04-21 devnull }
302 28994509 2004-04-21 devnull
303 28994509 2004-04-21 devnull static Rawimage*
304 28994509 2004-04-21 devnull readslave(Biobuf *b)
305 28994509 2004-04-21 devnull {
306 28994509 2004-04-21 devnull ZlibR zr;
307 28994509 2004-04-21 devnull ZlibW zw;
308 28994509 2004-04-21 devnull Rawimage *image;
309 28994509 2004-04-21 devnull char type[5];
310 28994509 2004-04-21 devnull uchar *buf, *h;
311 6a8f21b2 2005-03-18 devnull int k, n, nrow, ncol, err, bpp, nch;
312 28994509 2004-04-21 devnull
313 6a8f21b2 2005-03-18 devnull zr.w = &zw;
314 6a8f21b2 2005-03-18 devnull
315 28994509 2004-04-21 devnull buf = pngmalloc(IDATSIZE, 0);
316 28994509 2004-04-21 devnull Bread(b, buf, sizeof PNGmagic);
317 28994509 2004-04-21 devnull if(memcmp(PNGmagic, buf, sizeof PNGmagic) != 0)
318 28994509 2004-04-21 devnull sysfatal("bad PNGmagic");
319 28994509 2004-04-21 devnull
320 28994509 2004-04-21 devnull n = getchunk(b, type, buf, IDATSIZE);
321 28994509 2004-04-21 devnull if(n < 13 || strcmp(type,"IHDR") != 0)
322 28994509 2004-04-21 devnull sysfatal("missing IHDR chunk");
323 28994509 2004-04-21 devnull h = buf;
324 28994509 2004-04-21 devnull ncol = get4(h); h += 4;
325 28994509 2004-04-21 devnull nrow = get4(h); h += 4;
326 28994509 2004-04-21 devnull if(ncol <= 0 || nrow <= 0)
327 28994509 2004-04-21 devnull sysfatal("impossible image size nrow=%d ncol=%d", nrow, ncol);
328 28994509 2004-04-21 devnull if(debug)
329 28994509 2004-04-21 devnull fprint(2, "readpng nrow=%d ncol=%d\n", nrow, ncol);
330 6a8f21b2 2005-03-18 devnull
331 6a8f21b2 2005-03-18 devnull bpp = *h++;
332 6a8f21b2 2005-03-18 devnull nch = 0;
333 6a8f21b2 2005-03-18 devnull switch (*h++) {
334 6a8f21b2 2005-03-18 devnull case 0: /* grey */
335 6a8f21b2 2005-03-18 devnull nch = 1;
336 6a8f21b2 2005-03-18 devnull break;
337 6a8f21b2 2005-03-18 devnull case 2: /* rgb */
338 6a8f21b2 2005-03-18 devnull nch = 3;
339 6a8f21b2 2005-03-18 devnull break;
340 6a8f21b2 2005-03-18 devnull case 3: /* indexed rgb with PLTE */
341 6a8f21b2 2005-03-18 devnull nch = 1;
342 6a8f21b2 2005-03-18 devnull break;
343 6a8f21b2 2005-03-18 devnull case 4: /* grey+alpha */
344 6a8f21b2 2005-03-18 devnull nch = 2;
345 6a8f21b2 2005-03-18 devnull break;
346 6a8f21b2 2005-03-18 devnull case 6: /* rgb+alpha */
347 6a8f21b2 2005-03-18 devnull nch = 4;
348 6a8f21b2 2005-03-18 devnull break;
349 6a8f21b2 2005-03-18 devnull default:
350 6a8f21b2 2005-03-18 devnull sysfatal("unsupported color scheme %d", h[-1]);
351 6a8f21b2 2005-03-18 devnull }
352 6a8f21b2 2005-03-18 devnull
353 6a8f21b2 2005-03-18 devnull /* generate default palette for grayscale */
354 6a8f21b2 2005-03-18 devnull zw.palsize = 256;
355 6a8f21b2 2005-03-18 devnull if (nch < 3 && bpp < 9)
356 6a8f21b2 2005-03-18 devnull zw.palsize = 1<<bpp;
357 6a8f21b2 2005-03-18 devnull for (k = 0; k < zw.palsize; ++k) {
358 6a8f21b2 2005-03-18 devnull zw.palette[3*k] = (k*255)/(zw.palsize-1);
359 6a8f21b2 2005-03-18 devnull zw.palette[3*k+1] = (k*255)/(zw.palsize-1);
360 6a8f21b2 2005-03-18 devnull zw.palette[3*k+2] = (k*255)/(zw.palsize-1);
361 6a8f21b2 2005-03-18 devnull }
362 6a8f21b2 2005-03-18 devnull
363 28994509 2004-04-21 devnull if(*h++ != 0)
364 28994509 2004-04-21 devnull sysfatal("only deflate supported for now [%d]", h[-1]);
365 28994509 2004-04-21 devnull if(*h++ != FilterNone)
366 28994509 2004-04-21 devnull sysfatal("only FilterNone supported for now [%d]", h[-1]);
367 28994509 2004-04-21 devnull if(*h != 0)
368 28994509 2004-04-21 devnull sysfatal("only non-interlaced supported for now [%d]", h[-1]);
369 28994509 2004-04-21 devnull
370 28994509 2004-04-21 devnull image = pngmalloc(sizeof(Rawimage), 1);
371 28994509 2004-04-21 devnull image->r = Rect(0, 0, ncol, nrow);
372 28994509 2004-04-21 devnull image->cmap = nil;
373 28994509 2004-04-21 devnull image->cmaplen = 0;
374 28994509 2004-04-21 devnull image->chanlen = ncol*nrow;
375 28994509 2004-04-21 devnull image->fields = 0;
376 28994509 2004-04-21 devnull image->gifflags = 0;
377 28994509 2004-04-21 devnull image->gifdelay = 0;
378 28994509 2004-04-21 devnull image->giftrindex = 0;
379 28994509 2004-04-21 devnull image->chandesc = CRGB;
380 28994509 2004-04-21 devnull image->nchans = 3;
381 6a8f21b2 2005-03-18 devnull
382 6a8f21b2 2005-03-18 devnull zw.chanl = ncol*nrow;
383 6a8f21b2 2005-03-18 devnull zw.npix = 0;
384 6a8f21b2 2005-03-18 devnull for(k=0; k<4; k++)
385 6a8f21b2 2005-03-18 devnull image->chans[k] = zw.chan[k] = pngmalloc(ncol*nrow, 1);
386 6a8f21b2 2005-03-18 devnull
387 28994509 2004-04-21 devnull zr.bi = b;
388 28994509 2004-04-21 devnull zr.buf = buf;
389 28994509 2004-04-21 devnull zr.b = zr.e = buf + IDATSIZE;
390 6a8f21b2 2005-03-18 devnull
391 6a8f21b2 2005-03-18 devnull zw.scanp = 0;
392 28994509 2004-04-21 devnull zw.row = 0;
393 6a8f21b2 2005-03-18 devnull zw.scanpix = ncol;
394 6a8f21b2 2005-03-18 devnull zw.scanl = (nch*ncol*bpp+7)/8+1;
395 6a8f21b2 2005-03-18 devnull zw.scan = pngmalloc(zw.scanl, 1);
396 6a8f21b2 2005-03-18 devnull zw.pscan = pngmalloc(zw.scanl, 1);
397 6a8f21b2 2005-03-18 devnull zw.nchan = nch;
398 6a8f21b2 2005-03-18 devnull zw.bpp = bpp;
399 6a8f21b2 2005-03-18 devnull
400 28994509 2004-04-21 devnull err = inflatezlib(&zw, zwrite, &zr, zread);
401 6a8f21b2 2005-03-18 devnull
402 6a8f21b2 2005-03-18 devnull if (zw.npix > zw.chanl)
403 6a8f21b2 2005-03-18 devnull fprint(2, "tried to overflow by %d pix\n", zw.npix - zw.chanl);
404 6a8f21b2 2005-03-18 devnull
405 6a8f21b2 2005-03-18 devnull
406 28994509 2004-04-21 devnull if(err)
407 28994509 2004-04-21 devnull sysfatal("inflatezlib %s\n", flateerr(err));
408 6a8f21b2 2005-03-18 devnull
409 6a8f21b2 2005-03-18 devnull free(image->chans[3]);
410 6a8f21b2 2005-03-18 devnull image->chans[3] = nil;
411 28994509 2004-04-21 devnull free(buf);
412 6a8f21b2 2005-03-18 devnull free(zw.scan);
413 6a8f21b2 2005-03-18 devnull free(zw.pscan);
414 28994509 2004-04-21 devnull return image;
415 28994509 2004-04-21 devnull }
416 28994509 2004-04-21 devnull
417 28994509 2004-04-21 devnull Rawimage**
418 28994509 2004-04-21 devnull Breadpng(Biobuf *b, int colorspace)
419 28994509 2004-04-21 devnull {
420 28994509 2004-04-21 devnull Rawimage *r, **array;
421 28994509 2004-04-21 devnull char buf[ERRMAX];
422 28994509 2004-04-21 devnull
423 28994509 2004-04-21 devnull buf[0] = '\0';
424 28994509 2004-04-21 devnull if(colorspace != CRGB){
425 28994509 2004-04-21 devnull errstr(buf, sizeof buf); /* throw it away */
426 28994509 2004-04-21 devnull werrstr("ReadPNG: unknown color space %d", colorspace);
427 28994509 2004-04-21 devnull return nil;
428 28994509 2004-04-21 devnull }
429 28994509 2004-04-21 devnull pnginit();
430 28994509 2004-04-21 devnull array = malloc(2*sizeof(*array));
431 28994509 2004-04-21 devnull if(array==nil)
432 28994509 2004-04-21 devnull return nil;
433 28994509 2004-04-21 devnull errstr(buf, sizeof buf); /* throw it away */
434 28994509 2004-04-21 devnull r = readslave(b);
435 28994509 2004-04-21 devnull array[0] = r;
436 28994509 2004-04-21 devnull array[1] = nil;
437 28994509 2004-04-21 devnull return array;
438 28994509 2004-04-21 devnull }
439 28994509 2004-04-21 devnull
440 28994509 2004-04-21 devnull Rawimage**
441 28994509 2004-04-21 devnull readpng(int fd, int colorspace)
442 28994509 2004-04-21 devnull {
443 28994509 2004-04-21 devnull Rawimage** a;
444 28994509 2004-04-21 devnull Biobuf b;
445 28994509 2004-04-21 devnull
446 28994509 2004-04-21 devnull if(Binit(&b, fd, OREAD) < 0)
447 28994509 2004-04-21 devnull return nil;
448 28994509 2004-04-21 devnull a = Breadpng(&b, colorspace);
449 28994509 2004-04-21 devnull Bterm(&b);
450 28994509 2004-04-21 devnull return a;
451 28994509 2004-04-21 devnull }