1706
|
1 *
|
|
2 * GIF supervisor and LZW decoding stuff.
|
|
3 *
|
|
4
|
|
5 ifp1
|
|
6 use /dd/defs/os9defs.a
|
|
7 endc
|
|
8
|
|
9 psect view_gif_a,0,0,0,0,0
|
|
10
|
|
11 *
|
|
12 * GIFshowpic
|
|
13 *
|
|
14 * Display a GIF picture
|
|
15 *
|
|
16 vsect dp
|
|
17 * These are initialized by SetGIF in view_gifset.a
|
|
18 giftable: rmb 2 Pointer to 12k decode table
|
|
19 gifstack: rmb 2 Pointer to 4k space for reversing codes
|
|
20 * These are used by the actual screen output routines in view_gifpix.a
|
|
21 gifiheight: rmb 2 Image height
|
|
22 gifiwidth: rmb 2 image width
|
|
23 gifinterlace: rmb 1 T=Use interlace in displaying picture.
|
|
24 * These are all used locally.
|
|
25 sheight rmb 2 Screen height (We use the image size instead of these).
|
|
26 swidth rmb 2 Screen width
|
|
27 domap rmb 1 T= Color map follows
|
|
28 *cr rmb 1 Number bits of color resolution
|
|
29 pixel rmb 1 Number bits per pixel
|
|
30 background rmb 1 Background color
|
|
31 screenset rmb 1 T= screen has been set.
|
|
32 endsect
|
|
33
|
|
34 GIFshowpic:
|
|
35 clr screenset
|
|
36 lbsr signature Find signature in input stream
|
|
37 lbsr screendesc Parse the screen descriptor information
|
|
38 tst <domap
|
|
39 beq noglobal
|
|
40 lbsr colormap Read and parse the colormap and set up the screen.
|
|
41 clr <domap
|
|
42 noglobal
|
|
43 *
|
|
44 * Main image processing loop
|
|
45 * Searches the input stream for one of the following separator characters,
|
|
46 * and acts accordingly:
|
|
47 * 0x2c (comma) - GIF image follows
|
|
48 * 0x21 (exclamation point) - extension block follows
|
|
49 * 0x3b (semicolon) - end of GIF file
|
|
50 GIFLoop
|
|
51 lbsr I_GetByte
|
|
52 lbcs _error
|
|
53 cmpa #$3b semicolon marks the end of the file
|
|
54 beq GIFend
|
|
55 cmpa #$21
|
|
56 bne gif2
|
|
57 lbsr skipextension
|
|
58 bra GIFLoop
|
|
59 gif2
|
|
60 cmpa #$2c
|
|
61 bne GIFLoop
|
|
62 bsr gifimage
|
|
63 bra GIFLoop
|
|
64 GIFend
|
|
65 lbsr EndGIF Return extra memory area.
|
|
66 rts
|
|
67
|
|
68 vsect dp
|
|
69 mincode rmb 1 Starting code size
|
|
70 lastcode rmb 2 Last code input
|
|
71 thiscode rmb 2 the current code
|
|
72 endcode rmb 2 Code signifying end of picture
|
|
73 clrcode rmb 2 code indicating that we clear the table
|
|
74 firstcolor rmb 1 First color of code just processed
|
|
75 codesize rmb 1 Current code size in bits
|
|
76 *bethy rmb 50 How much I love Beth. (Needs to be MUCH bigger...)
|
|
77 endsect
|
|
78
|
|
79 * Process a GIF image
|
|
80 gifimage
|
|
81 pshs a,b,x,y,u
|
|
82 * First, handle the image descriptor
|
|
83 lbsr GIFgetword offset of pic from left edge of screen
|
|
84 lbsr GIFgetword offset of pic from top of screen
|
|
85 lbsr GIFgetword image width
|
|
86 std gifiwidth
|
|
87 lbsr GIFgetword image height
|
|
88 std gifiheight
|
|
89 lbsr I_GetByte bitmapped option byte
|
|
90 tfr a,b
|
|
91 sex
|
|
92 sta domap top bit: T=local map follows
|
|
93 tfr b,a
|
|
94 anda #$3
|
|
95 inca
|
|
96 sta pixel Bottom 3 bits: bits/pixel less one.
|
|
97 lslb
|
|
98 sex
|
|
99 sta gifinterlace Bit 6: T=Use interlace
|
|
100 tst domap Is there a local color map?
|
|
101 beq nolocal
|
|
102 lbsr colormap Yes, handle it.
|
|
103 nolocal
|
|
104 * Now, we're down to the actual image.
|
|
105 lbsr I_GetByte Get the starting code size.
|
|
106 sta mincode
|
|
107 cmpa #8 Does code size make sense?
|
|
108 bls gifcodeok
|
|
109 lbra E$Format No, report a format error.
|
|
110 gifcodeok
|
|
111 lbsr lzwinit Initialize some machinery
|
|
112 lbsr gifoutinit
|
|
113 * From here on, U holds the address of the next entry in the decode table.
|
|
114 lbsr clrtable Clear table, set endcode and clrcode
|
|
115 imageloop
|
|
116 lbsr nexttoken Get a code.
|
|
117 stx thiscode
|
|
118 cmpx endcode Is it an end-of-pic code?
|
|
119 beq imageend
|
|
120 cmpx clrcode Is it a clear code?
|
|
121 bne imagenormal
|
|
122 lbsr clrtable If so, reinitialize everything.
|
|
123 lbsr nexttoken Get the next token (always a root)
|
|
124 stx lastcode
|
|
125 lbsr outcode Output it.
|
|
126 bra imageloop
|
|
127 imagenormal
|
|
128 lbsr outcode Output the code, set the initial color var.
|
|
129 ldx lastcode
|
|
130 lda firstcolor
|
|
131 stx ,u++ Add the code to the decode table.
|
|
132 sta ,u+
|
|
133 cmpu <codelimit Are we at the point where we change code size?
|
|
134 blo addcend
|
|
135 lbsr setlimit Yes, do it.
|
|
136 addcend
|
|
137 ldx thiscode
|
|
138 stx lastcode
|
|
139 bra imageloop
|
|
140 imageend
|
|
141 puls a,b,x,y,u,pc
|
|
142
|
|
143 * This is an extension block, so skip it.
|
|
144 skipextension
|
|
145 pshs a,b,x,y
|
|
146 lbsr I_GetByte Get function code
|
|
147 extensloop
|
|
148 bsr getpacket Get packet, size in A.
|
|
149 tsta
|
|
150 bne extensloop Non-zero, get another.
|
|
151 puls a,b,x,y,pc
|
|
152
|
|
153 * Get a packet from input into AltBuff, return packet size in A.
|
|
154 getpacket
|
|
155 pshs b,x,y
|
|
156 lbsr I_GetByte
|
|
157 tsta
|
|
158 beq getpackend
|
|
159 pshs a
|
|
160 tfr a,b
|
|
161 clra
|
|
162 leax altbuff,y
|
|
163 tfr d,y
|
|
164 lbsr I_Read
|
|
165 lbcs _error
|
|
166 puls a
|
|
167 getpackend
|
|
168 puls b,x,y,pc
|
|
169
|
|
170 * Read and process colormap
|
|
171 colormap
|
|
172 pshs a,b,x,y,u
|
|
173 lda pixel
|
|
174 bsr powertwo
|
|
175 leax altbuff,y
|
|
176 leau alt2buff,y
|
|
177 pshs y
|
|
178 tfr d,y
|
|
179 leay d,y
|
|
180 leay d,y Y:=3*D
|
|
181 lbsr I_Read Read global color map
|
|
182 lbcs _error
|
|
183 puls y
|
|
184 tst <screenset Is screen already set?
|
|
185 bne endcmap Yes, don't process stuff.
|
|
186 com screenset No, mark it as set.
|
|
187 lbsr GIFcolors Translate colors, and generate color translation table.
|
|
188 lbsr setscreen
|
|
189 lbsr setbuffer
|
|
190 lbsr setpals Set the palettes
|
|
191 lda background Translate background color through the translation table
|
|
192 leau a,u
|
|
193 leau a,u
|
|
194 lda a,u
|
|
195 lbsr setborder Set the border color.
|
|
196 endcmap
|
|
197 puls a,b,x,y,u,pc
|
|
198
|
|
199 * Take value in A and return 2**A in D (assumes A<15).
|
|
200 powertwo
|
|
201 pshs a
|
|
202 ldd #1
|
|
203 tst ,s
|
|
204 powerloop
|
|
205 beq powerend
|
|
206 lslb
|
|
207 rola
|
|
208 dec ,s
|
|
209 bra powerloop
|
|
210 powerend
|
|
211 leas 1,s
|
|
212 rts
|
|
213
|
|
214 * Read and process screen descriptor
|
|
215 screendesc
|
|
216 pshs a,b
|
|
217 bsr GIFgetword
|
|
218 std swidth First word is screen width in pixels
|
|
219 bsr GIFgetword
|
|
220 std sheight Next is screen height in pixels
|
|
221 lbsr I_GetByte This is bit-mapped
|
|
222 lbcs _error Bit 7: T= global map follows
|
|
223 tfr a,b Bits 6:5:4: number bits of "color resolution" - 1
|
|
224 andb #7 Bits 2:1:0: Number of bits per pixel - 1
|
|
225 incb (Determines size of color map)
|
|
226 stb pixel
|
|
227 tfr a,b
|
|
228 sex
|
|
229 sta domap Top bit is true if global color map follows
|
|
230 lbsr I_GetByte
|
|
231 lbcs _error
|
|
232 sta background
|
|
233 lbsr I_GetByte
|
|
234 lbcs _error
|
|
235 tsta
|
|
236 lbne E$Format
|
|
237 puls a,b,pc
|
|
238
|
|
239 GIFgetword
|
|
240 lbsr I_GetByte
|
|
241 lbcs _error
|
|
242 tfr a,b
|
|
243 lbsr I_GetByte
|
|
244 lbcs _error
|
|
245 rts
|
|
246
|
|
247 * Signature: scan input to find "GIF###", the GIF signature string,
|
|
248 * where ### is two digits followed by a lowercase letter, e.g.
|
|
249 * '87a'
|
|
250 sigsub
|
|
251 lbsr I_GetByte
|
|
252 lbcs _error
|
|
253 rts
|
|
254
|
|
255 signature
|
|
256 pshs a,b
|
|
257 Sig0
|
|
258 bsr sigsub
|
|
259 Sig1
|
|
260 cmpa #'G Search for "GIF"
|
|
261 bne Sig0
|
|
262 bsr sigsub
|
|
263 cmpa #'I
|
|
264 bne Sig1
|
|
265 bsr sigsub
|
|
266 cmpa #'F
|
|
267 bne Sig1
|
|
268 clrb
|
|
269 Sig2
|
|
270 bsr sigsub Get two digits
|
|
271 cmpa #'0
|
|
272 blo Sig1
|
|
273 cmpa #'9
|
|
274 bhi Sig1
|
|
275 comb
|
|
276 bne Sig2
|
|
277 bsr sigsub and one lowercase letter
|
|
278 cmpa #'a
|
|
279 blo Sig1
|
|
280 cmpa #'z
|
|
281 bhi Sig1
|
|
282 puls a,b,pc
|
|
283
|
|
284
|
|
285 *
|
|
286 *LZW decode subs.
|
|
287 *
|
|
288 vsect dp
|
|
289 codelimit rmb 2 Point at which we must switch code sizes.
|
|
290 endsect
|
|
291
|
|
292 * Miscellaneous initialization
|
|
293 lzwinit
|
|
294 pshs a,b,x
|
|
295 clr <packsiz
|
|
296 clr <numbits
|
|
297 puls a,b,x,pc
|
|
298
|
|
299 * Initialize the decode table
|
|
300 *
|
|
301 clrtable
|
|
302 pshs a,b,x,y
|
|
303 ldx giftable Get start of table
|
|
304 lda mincode
|
|
305 lbsr powertwo
|
|
306 pshs y
|
|
307 tfr d,y
|
|
308 clra
|
|
309 clrb
|
|
310 clrloop
|
|
311 sta ,x+ Roots have 0 for pointer, themselves for suffix
|
|
312 std ,x++
|
|
313 incb
|
|
314 leay -1,y
|
|
315 bne clrloop
|
|
316 puls y
|
|
317 stx clrcode
|
|
318 leax 3,x
|
|
319 stx endcode
|
|
320 leax 3,x
|
|
321 tfr x,u Set up nextentry pointer in U
|
|
322 lda mincode
|
|
323 sta codesize Pretend we were doing "mincode".
|
|
324 lbsr setlimit Bump to next codesize.
|
|
325 puls a,b,x,y,pc
|
|
326
|
|
327 vsect dp
|
|
328 packptr rmb 2
|
|
329 packsiz rmb 1
|
|
330 endsect
|
|
331 * Return next byte from file
|
|
332 nextbyte
|
|
333 pshs x
|
|
334 tst packsiz
|
|
335 bne nextbyte1
|
|
336 lbsr getpacket
|
|
337 sta packsiz
|
|
338 leax altbuff,y
|
|
339 stx packptr
|
|
340 nextbyte1
|
|
341 dec packsiz
|
|
342 ldx packptr
|
|
343 lda ,x+
|
|
344 stx packptr
|
|
345 puls x,pc
|
|
346
|
|
347 vsect dp
|
|
348 numbits rmb 1 Number of bits in bit buffer
|
|
349 bitbuff rmb 3 Buffer bits from file here
|
|
350 codemask rmb 2 Mask off just codesize bits.
|
|
351 endsect
|
|
352 * Return next token from file
|
|
353 nexttoken
|
|
354 pshs d
|
|
355 ldb numbits First, fill bitbuffer with enough bits to make up codesize
|
|
356 bra nexttokst
|
|
357 nexttokloop
|
|
358 ldx bitbuff Move other 16 bits forward.
|
|
359 stx bitbuff+1
|
|
360 bsr nextbyte Get 8 more bits
|
|
361 sta bitbuff
|
|
362 addb #8 Increase bit count.
|
|
363 nexttokst
|
|
364 cmpb codesize
|
|
365 blo nexttokloop
|
|
366 stb numbits
|
|
367 cmpb #17 Do we have to deal with three bytes?
|
|
368 blo nexttok2 No, 16 or fewer bits, so just deal with two.
|
|
369 ldb #20
|
|
370 subb numbits First, we shift until we get to bit #20.
|
|
371 clra
|
|
372 tfr d,x
|
|
373 ldd bitbuff We keep first two bytes in D, leave 3rd one in place.
|
|
374 nexttok31
|
|
375 lsra Analysis shows that we are never past bit 19, so we will
|
|
376 rorb always have to process this loop at least once.
|
|
377 ror bitbuff+2
|
|
378 leax -1,x
|
|
379 bne nexttok31
|
|
380 tfr b,a Now, the first bit of the token we want is out of the first
|
|
381 ldb bitbuff+2 byte, so we're down to two bytes.
|
|
382 lsra
|
|
383 rorb Since we start with the least sig bit in bit #20, and we want it
|
|
384 lsra in bit #24, we must shift exactly 4 times.
|
|
385 rorb
|
|
386 lsra
|
|
387 rorb
|
|
388 lsra
|
|
389 rorb
|
|
390 bra nexttok10 Now we have our token.
|
|
391 nexttok2
|
|
392 cmpb #9 Do we have to deal with two bytes?
|
|
393 blo nexttok1
|
|
394 ldb #16
|
|
395 subb numbits
|
|
396 clra
|
|
397 tfr d,x
|
|
398 ldd bitbuff
|
|
399 stx -2,s Test X for zero.
|
|
400 beq nexttok10
|
|
401 nexttok21
|
|
402 lsra
|
|
403 rorb
|
|
404 leax -1,x
|
|
405 bne nexttok21
|
|
406 bra nexttok10
|
|
407 nexttok1
|
|
408 ldb bitbuff
|
|
409 lda #8
|
|
410 suba numbits
|
|
411 beq nexttok10
|
|
412 nexttok11
|
|
413 lsrb
|
|
414 deca
|
|
415 bne nexttok11
|
|
416 nexttok10
|
|
417 anda codemask
|
|
418 andb codemask+1
|
|
419 ldx <giftable
|
|
420 leax d,x
|
|
421 leax d,x
|
|
422 leax d,x
|
|
423 ldb numbits
|
|
424 subb codesize
|
|
425 stb numbits
|
|
426 puls d,pc
|
|
427
|
|
428 outcode
|
|
429 pshs a,b,x,y,u
|
|
430 ldu <gifstack
|
|
431 cmpx 6,s U is on the stack.
|
|
432 lbhi E$Format If the code is too large, report a format error
|
|
433 beq outcode1
|
|
434 bsr outcsub If it's in the table, process it.
|
|
435 bra outcode2
|
|
436 outcode1
|
|
437 ldx lastcode If it's not in the table, then it is the last code
|
|
438 bsr outcsub followed by the first color of the last code.
|
|
439 lda firstcolor
|
|
440 lbsr gifoutpix
|
|
441 outcode2
|
|
442 puls a,b,x,y,u,pc
|
|
443
|
|
444 outcsub
|
|
445 pshs y
|
|
446 ldy #0000
|
|
447 outc1
|
|
448 lda 2,x
|
|
449 leay 1,y
|
|
450 pshu a
|
|
451 ldx ,x
|
|
452 bne outc1
|
|
453 tfr y,x Put the count in X
|
|
454 puls y
|
|
455
|
|
456 sta firstcolor Now we know the first color, so store it.
|
|
457
|
|
458 outc2
|
|
459 pulu a
|
|
460 lbsr gifoutpix
|
|
461 leax -1,x
|
|
462 bne outc2
|
|
463 rts
|
|
464
|
|
465 * Add a code to the table
|
|
466 addcode
|
|
467 pshs a,b
|
|
468 puls a,b,pc
|
|
469
|
|
470 setlimit
|
|
471 pshs a,b,x
|
|
472 lda codesize
|
|
473 cmpa #12
|
|
474 bhs setlim1
|
|
475 inca
|
|
476 setlim1
|
|
477 sta codesize
|
|
478 lbsr powertwo
|
|
479 ldx giftable
|
|
480 leax d,x
|
|
481 leax d,x
|
|
482 leax d,x
|
|
483 stx codelimit
|
|
484 subd #1
|
|
485 std <codemask
|
|
486 puls a,b,x,pc
|
|
487
|
|
488 endsect
|