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 "imagefile.h"
6 28994509 2004-04-21 devnull
7 28994509 2004-04-21 devnull typedef struct Entry Entry;
8 28994509 2004-04-21 devnull typedef struct Header Header;
9 28994509 2004-04-21 devnull
10 28994509 2004-04-21 devnull struct Entry{
11 28994509 2004-04-21 devnull int prefix;
12 28994509 2004-04-21 devnull int exten;
13 28994509 2004-04-21 devnull };
14 28994509 2004-04-21 devnull
15 28994509 2004-04-21 devnull
16 28994509 2004-04-21 devnull struct Header{
17 28994509 2004-04-21 devnull Biobuf *fd;
18 28994509 2004-04-21 devnull char err[256];
19 28994509 2004-04-21 devnull jmp_buf errlab;
20 28994509 2004-04-21 devnull uchar buf[3*256];
21 28994509 2004-04-21 devnull char vers[8];
22 28994509 2004-04-21 devnull uchar *globalcmap;
23 28994509 2004-04-21 devnull int screenw;
24 28994509 2004-04-21 devnull int screenh;
25 28994509 2004-04-21 devnull int fields;
26 28994509 2004-04-21 devnull int bgrnd;
27 28994509 2004-04-21 devnull int aspect;
28 28994509 2004-04-21 devnull int flags;
29 28994509 2004-04-21 devnull int delay;
30 28994509 2004-04-21 devnull int trindex;
31 28994509 2004-04-21 devnull int loopcount;
32 28994509 2004-04-21 devnull Entry tbl[4096];
33 28994509 2004-04-21 devnull Rawimage **array;
34 28994509 2004-04-21 devnull Rawimage *new;
35 28994509 2004-04-21 devnull
36 28994509 2004-04-21 devnull uchar *pic;
37 28994509 2004-04-21 devnull };
38 28994509 2004-04-21 devnull
39 28994509 2004-04-21 devnull static char readerr[] = "ReadGIF: read error: %r";
40 28994509 2004-04-21 devnull static char extreaderr[] = "ReadGIF: can't read extension: %r";
41 28994509 2004-04-21 devnull static char memerr[] = "ReadGIF: malloc failed: %r";
42 28994509 2004-04-21 devnull
43 28994509 2004-04-21 devnull static Rawimage** readarray(Header*);
44 28994509 2004-04-21 devnull static Rawimage* readone(Header*);
45 28994509 2004-04-21 devnull static void readheader(Header*);
46 28994509 2004-04-21 devnull static void skipextension(Header*);
47 28994509 2004-04-21 devnull static uchar* readcmap(Header*, int);
48 28994509 2004-04-21 devnull static uchar* decode(Header*, Rawimage*, Entry*);
49 28994509 2004-04-21 devnull static void interlace(Header*, Rawimage*);
50 28994509 2004-04-21 devnull
51 28994509 2004-04-21 devnull static
52 28994509 2004-04-21 devnull void
53 28994509 2004-04-21 devnull clear(void *pp)
54 28994509 2004-04-21 devnull {
55 28994509 2004-04-21 devnull void **p = (void**)pp;
56 28994509 2004-04-21 devnull
57 28994509 2004-04-21 devnull if(*p){
58 28994509 2004-04-21 devnull free(*p);
59 28994509 2004-04-21 devnull *p = nil;
60 28994509 2004-04-21 devnull }
61 28994509 2004-04-21 devnull }
62 28994509 2004-04-21 devnull
63 28994509 2004-04-21 devnull static
64 28994509 2004-04-21 devnull void
65 28994509 2004-04-21 devnull giffreeall(Header *h, int freeimage)
66 28994509 2004-04-21 devnull {
67 28994509 2004-04-21 devnull int i;
68 28994509 2004-04-21 devnull
69 28994509 2004-04-21 devnull if(h->fd){
70 28994509 2004-04-21 devnull Bterm(h->fd);
71 28994509 2004-04-21 devnull h->fd = nil;
72 28994509 2004-04-21 devnull }
73 28994509 2004-04-21 devnull clear(&h->pic);
74 28994509 2004-04-21 devnull if(h->new){
75 28994509 2004-04-21 devnull clear(&h->new->cmap);
76 28994509 2004-04-21 devnull clear(&h->new->chans[0]);
77 28994509 2004-04-21 devnull clear(&h->new);
78 28994509 2004-04-21 devnull }
79 28994509 2004-04-21 devnull clear(&h->globalcmap);
80 28994509 2004-04-21 devnull if(freeimage && h->array!=nil){
81 28994509 2004-04-21 devnull for(i=0; h->array[i]; i++){
82 28994509 2004-04-21 devnull clear(&h->array[i]->cmap);
83 28994509 2004-04-21 devnull clear(&h->array[i]->chans[0]);
84 28994509 2004-04-21 devnull }
85 28994509 2004-04-21 devnull clear(&h->array);
86 28994509 2004-04-21 devnull }
87 28994509 2004-04-21 devnull }
88 28994509 2004-04-21 devnull
89 28994509 2004-04-21 devnull static
90 28994509 2004-04-21 devnull void
91 28994509 2004-04-21 devnull giferror(Header *h, char *fmt, ...)
92 28994509 2004-04-21 devnull {
93 28994509 2004-04-21 devnull va_list arg;
94 28994509 2004-04-21 devnull
95 28994509 2004-04-21 devnull va_start(arg, fmt);
96 28994509 2004-04-21 devnull vseprint(h->err, h->err+sizeof h->err, fmt, arg);
97 28994509 2004-04-21 devnull va_end(arg);
98 28994509 2004-04-21 devnull
99 28994509 2004-04-21 devnull werrstr(h->err);
100 28994509 2004-04-21 devnull giffreeall(h, 1);
101 28994509 2004-04-21 devnull longjmp(h->errlab, 1);
102 28994509 2004-04-21 devnull }
103 28994509 2004-04-21 devnull
104 28994509 2004-04-21 devnull
105 28994509 2004-04-21 devnull Rawimage**
106 28994509 2004-04-21 devnull readgif(int fd, int colorspace)
107 28994509 2004-04-21 devnull {
108 28994509 2004-04-21 devnull Rawimage **a;
109 28994509 2004-04-21 devnull Biobuf b;
110 28994509 2004-04-21 devnull Header *h;
111 28994509 2004-04-21 devnull char buf[ERRMAX];
112 28994509 2004-04-21 devnull
113 28994509 2004-04-21 devnull buf[0] = '\0';
114 28994509 2004-04-21 devnull USED(colorspace);
115 28994509 2004-04-21 devnull if(Binit(&b, fd, OREAD) < 0)
116 28994509 2004-04-21 devnull return nil;
117 28994509 2004-04-21 devnull h = malloc(sizeof(Header));
118 28994509 2004-04-21 devnull if(h == nil){
119 28994509 2004-04-21 devnull Bterm(&b);
120 28994509 2004-04-21 devnull return nil;
121 28994509 2004-04-21 devnull }
122 28994509 2004-04-21 devnull memset(h, 0, sizeof(Header));
123 28994509 2004-04-21 devnull h->fd = &b;
124 28994509 2004-04-21 devnull errstr(buf, sizeof buf); /* throw it away */
125 28994509 2004-04-21 devnull if(setjmp(h->errlab))
126 28994509 2004-04-21 devnull a = nil;
127 28994509 2004-04-21 devnull else
128 28994509 2004-04-21 devnull a = readarray(h);
129 28994509 2004-04-21 devnull giffreeall(h, 0);
130 28994509 2004-04-21 devnull free(h);
131 28994509 2004-04-21 devnull return a;
132 28994509 2004-04-21 devnull }
133 28994509 2004-04-21 devnull
134 28994509 2004-04-21 devnull static
135 28994509 2004-04-21 devnull void
136 28994509 2004-04-21 devnull inittbl(Header *h)
137 28994509 2004-04-21 devnull {
138 28994509 2004-04-21 devnull int i;
139 28994509 2004-04-21 devnull Entry *tbl;
140 28994509 2004-04-21 devnull
141 28994509 2004-04-21 devnull tbl = h->tbl;
142 28994509 2004-04-21 devnull for(i=0; i<258; i++) {
143 28994509 2004-04-21 devnull tbl[i].prefix = -1;
144 28994509 2004-04-21 devnull tbl[i].exten = i;
145 28994509 2004-04-21 devnull }
146 28994509 2004-04-21 devnull }
147 28994509 2004-04-21 devnull
148 28994509 2004-04-21 devnull static
149 28994509 2004-04-21 devnull Rawimage**
150 28994509 2004-04-21 devnull readarray(Header *h)
151 28994509 2004-04-21 devnull {
152 28994509 2004-04-21 devnull Entry *tbl;
153 28994509 2004-04-21 devnull Rawimage *new, **array;
154 28994509 2004-04-21 devnull int c, nimages;
155 28994509 2004-04-21 devnull
156 28994509 2004-04-21 devnull tbl = h->tbl;
157 28994509 2004-04-21 devnull
158 28994509 2004-04-21 devnull readheader(h);
159 28994509 2004-04-21 devnull
160 28994509 2004-04-21 devnull if(h->fields & 0x80)
161 28994509 2004-04-21 devnull h->globalcmap = readcmap(h, (h->fields&7)+1);
162 28994509 2004-04-21 devnull
163 28994509 2004-04-21 devnull array = malloc(sizeof(Rawimage**));
164 28994509 2004-04-21 devnull if(array == nil)
165 28994509 2004-04-21 devnull giferror(h, memerr);
166 28994509 2004-04-21 devnull nimages = 0;
167 28994509 2004-04-21 devnull array[0] = nil;
168 28994509 2004-04-21 devnull h->array = array;
169 fa325e9b 2020-01-10 cross
170 28994509 2004-04-21 devnull for(;;){
171 28994509 2004-04-21 devnull switch(c = Bgetc(h->fd)){
172 28994509 2004-04-21 devnull case Beof:
173 28994509 2004-04-21 devnull goto Return;
174 28994509 2004-04-21 devnull
175 28994509 2004-04-21 devnull case 0x21: /* Extension (ignored) */
176 28994509 2004-04-21 devnull skipextension(h);
177 28994509 2004-04-21 devnull break;
178 28994509 2004-04-21 devnull
179 28994509 2004-04-21 devnull case 0x2C: /* Image Descriptor */
180 28994509 2004-04-21 devnull inittbl(h);
181 28994509 2004-04-21 devnull new = readone(h);
182 28994509 2004-04-21 devnull if(new->fields & 0x80){
183 28994509 2004-04-21 devnull new->cmaplen = 3*(1<<((new->fields&7)+1));
184 28994509 2004-04-21 devnull new->cmap = readcmap(h, (new->fields&7)+1);
185 28994509 2004-04-21 devnull }else{
186 28994509 2004-04-21 devnull new->cmaplen = 3*(1<<((h->fields&7)+1));
187 28994509 2004-04-21 devnull new->cmap = malloc(new->cmaplen);
188 28994509 2004-04-21 devnull memmove(new->cmap, h->globalcmap, new->cmaplen);
189 28994509 2004-04-21 devnull }
190 28994509 2004-04-21 devnull h->new = new;
191 28994509 2004-04-21 devnull new->chans[0] = decode(h, new, tbl);
192 28994509 2004-04-21 devnull if(new->fields & 0x40)
193 28994509 2004-04-21 devnull interlace(h, new);
194 28994509 2004-04-21 devnull new->gifflags = h->flags;
195 28994509 2004-04-21 devnull new->gifdelay = h->delay;
196 28994509 2004-04-21 devnull new->giftrindex = h->trindex;
197 28994509 2004-04-21 devnull new->gifloopcount = h->loopcount;
198 28994509 2004-04-21 devnull array = realloc(h->array, (nimages+2)*sizeof(Rawimage*));
199 28994509 2004-04-21 devnull if(array == nil)
200 28994509 2004-04-21 devnull giferror(h, memerr);
201 28994509 2004-04-21 devnull array[nimages++] = new;
202 28994509 2004-04-21 devnull array[nimages] = nil;
203 28994509 2004-04-21 devnull h->array = array;
204 28994509 2004-04-21 devnull h->new = nil;
205 28994509 2004-04-21 devnull break;
206 28994509 2004-04-21 devnull
207 28994509 2004-04-21 devnull case 0x3B: /* Trailer */
208 28994509 2004-04-21 devnull goto Return;
209 28994509 2004-04-21 devnull
210 28994509 2004-04-21 devnull default:
211 28994509 2004-04-21 devnull fprint(2, "ReadGIF: unknown block type: 0x%.2x\n", c);
212 28994509 2004-04-21 devnull goto Return;
213 28994509 2004-04-21 devnull }
214 28994509 2004-04-21 devnull }
215 28994509 2004-04-21 devnull
216 28994509 2004-04-21 devnull Return:
217 28994509 2004-04-21 devnull if(array[0]==nil || array[0]->chans[0] == nil)
218 28994509 2004-04-21 devnull giferror(h, "ReadGIF: no picture in file");
219 28994509 2004-04-21 devnull
220 28994509 2004-04-21 devnull return array;
221 28994509 2004-04-21 devnull }
222 28994509 2004-04-21 devnull
223 28994509 2004-04-21 devnull static
224 28994509 2004-04-21 devnull void
225 28994509 2004-04-21 devnull readheader(Header *h)
226 28994509 2004-04-21 devnull {
227 28994509 2004-04-21 devnull if(Bread(h->fd, h->buf, 13) != 13)
228 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't read header: %r");
229 28994509 2004-04-21 devnull memmove(h->vers, h->buf, 6);
230 28994509 2004-04-21 devnull if(strcmp(h->vers, "GIF87a")!=0 && strcmp(h->vers, "GIF89a")!=0)
231 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't recognize format %s", h->vers);
232 28994509 2004-04-21 devnull h->screenw = h->buf[6]+(h->buf[7]<<8);
233 28994509 2004-04-21 devnull h->screenh = h->buf[8]+(h->buf[9]<<8);
234 28994509 2004-04-21 devnull h->fields = h->buf[10];
235 28994509 2004-04-21 devnull h->bgrnd = h->buf[11];
236 28994509 2004-04-21 devnull h->aspect = h->buf[12];
237 28994509 2004-04-21 devnull h->flags = 0;
238 28994509 2004-04-21 devnull h->delay = 0;
239 28994509 2004-04-21 devnull h->trindex = 0;
240 28994509 2004-04-21 devnull h->loopcount = -1;
241 28994509 2004-04-21 devnull }
242 28994509 2004-04-21 devnull
243 28994509 2004-04-21 devnull static
244 28994509 2004-04-21 devnull uchar*
245 28994509 2004-04-21 devnull readcmap(Header *h, int size)
246 28994509 2004-04-21 devnull {
247 28994509 2004-04-21 devnull uchar *map;
248 28994509 2004-04-21 devnull
249 28994509 2004-04-21 devnull if(size > 8)
250 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't handles %d bits per pixel", size);
251 28994509 2004-04-21 devnull size = 3*(1<<size);
252 28994509 2004-04-21 devnull if(Bread(h->fd, h->buf, size) != size)
253 28994509 2004-04-21 devnull giferror(h, "ReadGIF: short read on color map");
254 28994509 2004-04-21 devnull map = malloc(size);
255 28994509 2004-04-21 devnull if(map == nil)
256 28994509 2004-04-21 devnull giferror(h, memerr);
257 28994509 2004-04-21 devnull memmove(map, h->buf, size);
258 28994509 2004-04-21 devnull return map;
259 28994509 2004-04-21 devnull }
260 28994509 2004-04-21 devnull
261 28994509 2004-04-21 devnull static
262 28994509 2004-04-21 devnull Rawimage*
263 28994509 2004-04-21 devnull readone(Header *h)
264 28994509 2004-04-21 devnull {
265 28994509 2004-04-21 devnull Rawimage *i;
266 28994509 2004-04-21 devnull int left, top, width, height;
267 28994509 2004-04-21 devnull
268 28994509 2004-04-21 devnull if(Bread(h->fd, h->buf, 9) != 9)
269 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't read image descriptor: %r");
270 28994509 2004-04-21 devnull i = malloc(sizeof(Rawimage));
271 28994509 2004-04-21 devnull if(i == nil)
272 28994509 2004-04-21 devnull giferror(h, memerr);
273 28994509 2004-04-21 devnull left = h->buf[0]+(h->buf[1]<<8);
274 28994509 2004-04-21 devnull top = h->buf[2]+(h->buf[3]<<8);
275 28994509 2004-04-21 devnull width = h->buf[4]+(h->buf[5]<<8);
276 28994509 2004-04-21 devnull height = h->buf[6]+(h->buf[7]<<8);
277 28994509 2004-04-21 devnull i->fields = h->buf[8];
278 28994509 2004-04-21 devnull i->r.min.x = left;
279 28994509 2004-04-21 devnull i->r.min.y = top;
280 28994509 2004-04-21 devnull i->r.max.x = left+width;
281 28994509 2004-04-21 devnull i->r.max.y = top+height;
282 28994509 2004-04-21 devnull i->nchans = 1;
283 28994509 2004-04-21 devnull i->chandesc = CRGB1;
284 28994509 2004-04-21 devnull return i;
285 28994509 2004-04-21 devnull }
286 28994509 2004-04-21 devnull
287 28994509 2004-04-21 devnull
288 28994509 2004-04-21 devnull static
289 28994509 2004-04-21 devnull int
290 28994509 2004-04-21 devnull readdata(Header *h, uchar *data)
291 28994509 2004-04-21 devnull {
292 28994509 2004-04-21 devnull int nbytes, n;
293 28994509 2004-04-21 devnull
294 28994509 2004-04-21 devnull nbytes = Bgetc(h->fd);
295 28994509 2004-04-21 devnull if(nbytes < 0)
296 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't read data: %r");
297 28994509 2004-04-21 devnull if(nbytes == 0)
298 28994509 2004-04-21 devnull return 0;
299 28994509 2004-04-21 devnull n = Bread(h->fd, data, nbytes);
300 28994509 2004-04-21 devnull if(n < 0)
301 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't read data: %r");
302 28994509 2004-04-21 devnull if(n != nbytes)
303 28994509 2004-04-21 devnull fprint(2, "ReadGIF: short data subblock\n");
304 28994509 2004-04-21 devnull return n;
305 28994509 2004-04-21 devnull }
306 28994509 2004-04-21 devnull
307 28994509 2004-04-21 devnull static
308 28994509 2004-04-21 devnull void
309 28994509 2004-04-21 devnull graphiccontrol(Header *h)
310 28994509 2004-04-21 devnull {
311 28994509 2004-04-21 devnull if(Bread(h->fd, h->buf, 5+1) != 5+1)
312 28994509 2004-04-21 devnull giferror(h, readerr);
313 28994509 2004-04-21 devnull h->flags = h->buf[1];
314 28994509 2004-04-21 devnull h->delay = h->buf[2]+(h->buf[3]<<8);
315 28994509 2004-04-21 devnull h->trindex = h->buf[4];
316 28994509 2004-04-21 devnull }
317 28994509 2004-04-21 devnull
318 28994509 2004-04-21 devnull static
319 28994509 2004-04-21 devnull void
320 28994509 2004-04-21 devnull skipextension(Header *h)
321 28994509 2004-04-21 devnull {
322 28994509 2004-04-21 devnull int type, hsize, hasdata, n;
323 28994509 2004-04-21 devnull uchar data[256];
324 28994509 2004-04-21 devnull
325 28994509 2004-04-21 devnull hsize = 0;
326 28994509 2004-04-21 devnull hasdata = 0;
327 28994509 2004-04-21 devnull
328 28994509 2004-04-21 devnull type = Bgetc(h->fd);
329 28994509 2004-04-21 devnull switch(type){
330 28994509 2004-04-21 devnull case Beof:
331 28994509 2004-04-21 devnull giferror(h, extreaderr);
332 28994509 2004-04-21 devnull break;
333 28994509 2004-04-21 devnull case 0x01: /* Plain Text Extension */
334 28994509 2004-04-21 devnull hsize = 13;
335 28994509 2004-04-21 devnull hasdata = 1;
336 28994509 2004-04-21 devnull break;
337 28994509 2004-04-21 devnull case 0xF9: /* Graphic Control Extension */
338 28994509 2004-04-21 devnull graphiccontrol(h);
339 28994509 2004-04-21 devnull return;
340 28994509 2004-04-21 devnull case 0xFE: /* Comment Extension */
341 28994509 2004-04-21 devnull hasdata = 1;
342 28994509 2004-04-21 devnull break;
343 28994509 2004-04-21 devnull case 0xFF: /* Application Extension */
344 28994509 2004-04-21 devnull hsize = Bgetc(h->fd);
345 28994509 2004-04-21 devnull /* standard says this must be 11, but Adobe likes to put out 10-byte ones,
346 28994509 2004-04-21 devnull * so we pay attention to the field. */
347 28994509 2004-04-21 devnull hasdata = 1;
348 28994509 2004-04-21 devnull break;
349 28994509 2004-04-21 devnull default:
350 28994509 2004-04-21 devnull giferror(h, "ReadGIF: unknown extension");
351 28994509 2004-04-21 devnull }
352 28994509 2004-04-21 devnull if(hsize>0 && Bread(h->fd, h->buf, hsize) != hsize)
353 28994509 2004-04-21 devnull giferror(h, extreaderr);
354 ada24b40 2008-05-10 rsc if(!hasdata)
355 28994509 2004-04-21 devnull return;
356 28994509 2004-04-21 devnull
357 28994509 2004-04-21 devnull /* loop counter: Application Extension with NETSCAPE2.0 as string and 1 <loop.count> in data */
358 28994509 2004-04-21 devnull if(type == 0xFF && hsize==11 && memcmp(h->buf, "NETSCAPE2.0", 11)==0){
359 28994509 2004-04-21 devnull n = readdata(h, data);
360 28994509 2004-04-21 devnull if(n == 0)
361 28994509 2004-04-21 devnull return;
362 28994509 2004-04-21 devnull if(n==3 && data[0]==1)
363 28994509 2004-04-21 devnull h->loopcount = data[1] | (data[2]<<8);
364 28994509 2004-04-21 devnull }
365 28994509 2004-04-21 devnull while(readdata(h, data) != 0)
366 28994509 2004-04-21 devnull ;
367 28994509 2004-04-21 devnull }
368 28994509 2004-04-21 devnull
369 28994509 2004-04-21 devnull static
370 28994509 2004-04-21 devnull uchar*
371 28994509 2004-04-21 devnull decode(Header *h, Rawimage *i, Entry *tbl)
372 28994509 2004-04-21 devnull {
373 28994509 2004-04-21 devnull int c, incode, codesize, CTM, EOD, pici, datai, stacki, nbits, sreg, fc, code, piclen;
374 28994509 2004-04-21 devnull int csize, nentry, maxentry, first, ocode, ndata, nb;
375 28994509 2004-04-21 devnull uchar *pic;
376 28994509 2004-04-21 devnull uchar stack[4096], data[256];
377 28994509 2004-04-21 devnull
378 28994509 2004-04-21 devnull if(Bread(h->fd, h->buf, 1) != 1)
379 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't read data: %r");
380 28994509 2004-04-21 devnull codesize = h->buf[0];
381 28994509 2004-04-21 devnull if(codesize>8 || 0>codesize)
382 28994509 2004-04-21 devnull giferror(h, "ReadGIF: can't handle codesize %d", codesize);
383 28994509 2004-04-21 devnull if(i->cmap!=nil && i->cmaplen!=3*(1<<codesize)
384 28994509 2004-04-21 devnull && (codesize!=2 || i->cmaplen!=3*2)) /* peculiar GIF bitmap files... */
385 28994509 2004-04-21 devnull giferror(h, "ReadGIF: codesize %d doesn't match color map 3*%d", codesize, i->cmaplen/3);
386 28994509 2004-04-21 devnull
387 28994509 2004-04-21 devnull CTM =1<<codesize;
388 28994509 2004-04-21 devnull EOD = CTM+1;
389 28994509 2004-04-21 devnull
390 28994509 2004-04-21 devnull piclen = (i->r.max.x-i->r.min.x)*(i->r.max.y-i->r.min.y);
391 28994509 2004-04-21 devnull i->chanlen = piclen;
392 28994509 2004-04-21 devnull pic = malloc(piclen);
393 28994509 2004-04-21 devnull if(pic == nil)
394 28994509 2004-04-21 devnull giferror(h, memerr);
395 28994509 2004-04-21 devnull h->pic = pic;
396 28994509 2004-04-21 devnull pici = 0;
397 28994509 2004-04-21 devnull ndata = 0;
398 28994509 2004-04-21 devnull datai = 0;
399 28994509 2004-04-21 devnull nbits = 0;
400 28994509 2004-04-21 devnull sreg = 0;
401 28994509 2004-04-21 devnull fc = 0;
402 28994509 2004-04-21 devnull
403 28994509 2004-04-21 devnull Loop:
404 28994509 2004-04-21 devnull for(;;){
405 28994509 2004-04-21 devnull csize = codesize+1;
406 28994509 2004-04-21 devnull nentry = EOD+1;
407 28994509 2004-04-21 devnull maxentry = (1<<csize)-1;
408 28994509 2004-04-21 devnull first = 1;
409 28994509 2004-04-21 devnull ocode = -1;
410 28994509 2004-04-21 devnull
411 28994509 2004-04-21 devnull for(;; ocode = incode) {
412 28994509 2004-04-21 devnull while(nbits < csize) {
413 28994509 2004-04-21 devnull if(datai == ndata){
414 28994509 2004-04-21 devnull ndata = readdata(h, data);
415 28994509 2004-04-21 devnull if(ndata == 0)
416 28994509 2004-04-21 devnull goto Return;
417 28994509 2004-04-21 devnull datai = 0;
418 28994509 2004-04-21 devnull }
419 28994509 2004-04-21 devnull c = data[datai++];
420 28994509 2004-04-21 devnull sreg |= c<<nbits;
421 28994509 2004-04-21 devnull nbits += 8;
422 28994509 2004-04-21 devnull }
423 28994509 2004-04-21 devnull code = sreg & ((1<<csize) - 1);
424 28994509 2004-04-21 devnull sreg >>= csize;
425 28994509 2004-04-21 devnull nbits -= csize;
426 28994509 2004-04-21 devnull
427 28994509 2004-04-21 devnull if(code == EOD){
428 28994509 2004-04-21 devnull ndata = readdata(h, data);
429 28994509 2004-04-21 devnull if(ndata != 0)
430 28994509 2004-04-21 devnull fprint(2, "ReadGIF: unexpected data past EOD");
431 28994509 2004-04-21 devnull goto Return;
432 28994509 2004-04-21 devnull }
433 28994509 2004-04-21 devnull
434 28994509 2004-04-21 devnull if(code == CTM)
435 28994509 2004-04-21 devnull goto Loop;
436 28994509 2004-04-21 devnull
437 28994509 2004-04-21 devnull stacki = (sizeof stack)-1;
438 28994509 2004-04-21 devnull
439 28994509 2004-04-21 devnull incode = code;
440 28994509 2004-04-21 devnull
441 28994509 2004-04-21 devnull /* special case for KwKwK */
442 28994509 2004-04-21 devnull if(code == nentry) {
443 28994509 2004-04-21 devnull stack[stacki--] = fc;
444 28994509 2004-04-21 devnull code = ocode;
445 28994509 2004-04-21 devnull }
446 28994509 2004-04-21 devnull
447 28994509 2004-04-21 devnull if(code > nentry)
448 28994509 2004-04-21 devnull giferror(h, "ReadGIF: bad code %x %x", code, nentry);
449 28994509 2004-04-21 devnull
450 28994509 2004-04-21 devnull for(c=code; c>=0; c=tbl[c].prefix)
451 28994509 2004-04-21 devnull stack[stacki--] = tbl[c].exten;
452 28994509 2004-04-21 devnull
453 28994509 2004-04-21 devnull nb = (sizeof stack)-(stacki+1);
454 28994509 2004-04-21 devnull if(pici+nb > piclen){
455 28994509 2004-04-21 devnull /* this common error is harmless
456 28994509 2004-04-21 devnull * we have to keep reading to keep the blocks in sync */
457 28994509 2004-04-21 devnull ;
458 28994509 2004-04-21 devnull }else{
459 28994509 2004-04-21 devnull memmove(pic+pici, stack+stacki+1, sizeof stack - (stacki+1));
460 28994509 2004-04-21 devnull pici += nb;
461 28994509 2004-04-21 devnull }
462 28994509 2004-04-21 devnull
463 28994509 2004-04-21 devnull fc = stack[stacki+1];
464 28994509 2004-04-21 devnull
465 28994509 2004-04-21 devnull if(first){
466 28994509 2004-04-21 devnull first = 0;
467 28994509 2004-04-21 devnull continue;
468 28994509 2004-04-21 devnull }
469 28994509 2004-04-21 devnull #define early 0 /* peculiar tiff feature here for reference */
470 28994509 2004-04-21 devnull if(nentry == maxentry-early) {
471 28994509 2004-04-21 devnull if(csize >= 12)
472 28994509 2004-04-21 devnull continue;
473 28994509 2004-04-21 devnull csize++;
474 28994509 2004-04-21 devnull maxentry = (1<<csize);
475 28994509 2004-04-21 devnull if(csize < 12)
476 28994509 2004-04-21 devnull maxentry--;
477 28994509 2004-04-21 devnull }
478 28994509 2004-04-21 devnull tbl[nentry].prefix = ocode;
479 28994509 2004-04-21 devnull tbl[nentry].exten = fc;
480 28994509 2004-04-21 devnull nentry++;
481 28994509 2004-04-21 devnull }
482 28994509 2004-04-21 devnull }
483 28994509 2004-04-21 devnull
484 28994509 2004-04-21 devnull Return:
485 28994509 2004-04-21 devnull h->pic = nil;
486 28994509 2004-04-21 devnull return pic;
487 28994509 2004-04-21 devnull }
488 28994509 2004-04-21 devnull
489 28994509 2004-04-21 devnull static
490 28994509 2004-04-21 devnull void
491 28994509 2004-04-21 devnull interlace(Header *h, Rawimage *image)
492 28994509 2004-04-21 devnull {
493 28994509 2004-04-21 devnull uchar *pic;
494 28994509 2004-04-21 devnull Rectangle r;
495 28994509 2004-04-21 devnull int dx, yy, y;
496 28994509 2004-04-21 devnull uchar *ipic;
497 28994509 2004-04-21 devnull
498 28994509 2004-04-21 devnull pic = image->chans[0];
499 28994509 2004-04-21 devnull r = image->r;
500 28994509 2004-04-21 devnull dx = r.max.x-r.min.x;
501 28994509 2004-04-21 devnull ipic = malloc(dx*(r.max.y-r.min.y));
502 28994509 2004-04-21 devnull if(ipic == nil)
503 28994509 2004-04-21 devnull giferror(h, nil);
504 28994509 2004-04-21 devnull
505 28994509 2004-04-21 devnull /* Group 1: every 8th row, starting with row 0 */
506 28994509 2004-04-21 devnull yy = 0;
507 28994509 2004-04-21 devnull for(y=r.min.y; y<r.max.y; y+=8){
508 28994509 2004-04-21 devnull memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
509 28994509 2004-04-21 devnull yy++;
510 28994509 2004-04-21 devnull }
511 28994509 2004-04-21 devnull
512 28994509 2004-04-21 devnull /* Group 2: every 8th row, starting with row 4 */
513 28994509 2004-04-21 devnull for(y=r.min.y+4; y<r.max.y; y+=8){
514 28994509 2004-04-21 devnull memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
515 28994509 2004-04-21 devnull yy++;
516 28994509 2004-04-21 devnull }
517 28994509 2004-04-21 devnull
518 28994509 2004-04-21 devnull /* Group 3: every 4th row, starting with row 2 */
519 28994509 2004-04-21 devnull for(y=r.min.y+2; y<r.max.y; y+=4){
520 28994509 2004-04-21 devnull memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
521 28994509 2004-04-21 devnull yy++;
522 28994509 2004-04-21 devnull }
523 28994509 2004-04-21 devnull
524 28994509 2004-04-21 devnull /* Group 4: every 2nd row, starting with row 1 */
525 28994509 2004-04-21 devnull for(y=r.min.y+1; y<r.max.y; y+=2){
526 28994509 2004-04-21 devnull memmove(&ipic[(y-r.min.y)*dx], &pic[yy*dx], dx);
527 28994509 2004-04-21 devnull yy++;
528 28994509 2004-04-21 devnull }
529 28994509 2004-04-21 devnull
530 28994509 2004-04-21 devnull free(image->chans[0]);
531 28994509 2004-04-21 devnull image->chans[0] = ipic;
532 28994509 2004-04-21 devnull }