Mercurial > hg > Members > kono > nitros9-code
diff 3rdparty/utils/view/view_gif.a @ 1706:6b23465701c0
Tim Kientzle's VIEW
author | boisy |
---|---|
date | Tue, 10 Aug 2004 23:46:24 +0000 |
parents | |
children | b7fb6a9aead4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/utils/view/view_gif.a Tue Aug 10 23:46:24 2004 +0000 @@ -0,0 +1,488 @@ +* +* GIF supervisor and LZW decoding stuff. +* + + ifp1 + use /dd/defs/os9defs.a + endc + + psect view_gif_a,0,0,0,0,0 + +* +* GIFshowpic +* +* Display a GIF picture +* + vsect dp +* These are initialized by SetGIF in view_gifset.a +giftable: rmb 2 Pointer to 12k decode table +gifstack: rmb 2 Pointer to 4k space for reversing codes +* These are used by the actual screen output routines in view_gifpix.a +gifiheight: rmb 2 Image height +gifiwidth: rmb 2 image width +gifinterlace: rmb 1 T=Use interlace in displaying picture. +* These are all used locally. +sheight rmb 2 Screen height (We use the image size instead of these). +swidth rmb 2 Screen width +domap rmb 1 T= Color map follows +*cr rmb 1 Number bits of color resolution +pixel rmb 1 Number bits per pixel +background rmb 1 Background color +screenset rmb 1 T= screen has been set. + endsect + +GIFshowpic: + clr screenset + lbsr signature Find signature in input stream + lbsr screendesc Parse the screen descriptor information + tst <domap + beq noglobal + lbsr colormap Read and parse the colormap and set up the screen. + clr <domap +noglobal +* +* Main image processing loop +* Searches the input stream for one of the following separator characters, +* and acts accordingly: +* 0x2c (comma) - GIF image follows +* 0x21 (exclamation point) - extension block follows +* 0x3b (semicolon) - end of GIF file +GIFLoop + lbsr I_GetByte + lbcs _error + cmpa #$3b semicolon marks the end of the file + beq GIFend + cmpa #$21 + bne gif2 + lbsr skipextension + bra GIFLoop +gif2 + cmpa #$2c + bne GIFLoop + bsr gifimage + bra GIFLoop +GIFend + lbsr EndGIF Return extra memory area. + rts + + vsect dp +mincode rmb 1 Starting code size +lastcode rmb 2 Last code input +thiscode rmb 2 the current code +endcode rmb 2 Code signifying end of picture +clrcode rmb 2 code indicating that we clear the table +firstcolor rmb 1 First color of code just processed +codesize rmb 1 Current code size in bits +*bethy rmb 50 How much I love Beth. (Needs to be MUCH bigger...) + endsect + +* Process a GIF image +gifimage + pshs a,b,x,y,u +* First, handle the image descriptor + lbsr GIFgetword offset of pic from left edge of screen + lbsr GIFgetword offset of pic from top of screen + lbsr GIFgetword image width + std gifiwidth + lbsr GIFgetword image height + std gifiheight + lbsr I_GetByte bitmapped option byte + tfr a,b + sex + sta domap top bit: T=local map follows + tfr b,a + anda #$3 + inca + sta pixel Bottom 3 bits: bits/pixel less one. + lslb + sex + sta gifinterlace Bit 6: T=Use interlace + tst domap Is there a local color map? + beq nolocal + lbsr colormap Yes, handle it. +nolocal +* Now, we're down to the actual image. + lbsr I_GetByte Get the starting code size. + sta mincode + cmpa #8 Does code size make sense? + bls gifcodeok + lbra E$Format No, report a format error. +gifcodeok + lbsr lzwinit Initialize some machinery + lbsr gifoutinit +* From here on, U holds the address of the next entry in the decode table. + lbsr clrtable Clear table, set endcode and clrcode +imageloop + lbsr nexttoken Get a code. + stx thiscode + cmpx endcode Is it an end-of-pic code? + beq imageend + cmpx clrcode Is it a clear code? + bne imagenormal + lbsr clrtable If so, reinitialize everything. + lbsr nexttoken Get the next token (always a root) + stx lastcode + lbsr outcode Output it. + bra imageloop +imagenormal + lbsr outcode Output the code, set the initial color var. + ldx lastcode + lda firstcolor + stx ,u++ Add the code to the decode table. + sta ,u+ + cmpu <codelimit Are we at the point where we change code size? + blo addcend + lbsr setlimit Yes, do it. +addcend + ldx thiscode + stx lastcode + bra imageloop +imageend + puls a,b,x,y,u,pc + +* This is an extension block, so skip it. +skipextension + pshs a,b,x,y + lbsr I_GetByte Get function code +extensloop + bsr getpacket Get packet, size in A. + tsta + bne extensloop Non-zero, get another. + puls a,b,x,y,pc + +* Get a packet from input into AltBuff, return packet size in A. +getpacket + pshs b,x,y + lbsr I_GetByte + tsta + beq getpackend + pshs a + tfr a,b + clra + leax altbuff,y + tfr d,y + lbsr I_Read + lbcs _error + puls a +getpackend + puls b,x,y,pc + +* Read and process colormap +colormap + pshs a,b,x,y,u + lda pixel + bsr powertwo + leax altbuff,y + leau alt2buff,y + pshs y + tfr d,y + leay d,y + leay d,y Y:=3*D + lbsr I_Read Read global color map + lbcs _error + puls y + tst <screenset Is screen already set? + bne endcmap Yes, don't process stuff. + com screenset No, mark it as set. + lbsr GIFcolors Translate colors, and generate color translation table. + lbsr setscreen + lbsr setbuffer + lbsr setpals Set the palettes + lda background Translate background color through the translation table + leau a,u + leau a,u + lda a,u + lbsr setborder Set the border color. +endcmap + puls a,b,x,y,u,pc + +* Take value in A and return 2**A in D (assumes A<15). +powertwo + pshs a + ldd #1 + tst ,s +powerloop + beq powerend + lslb + rola + dec ,s + bra powerloop +powerend + leas 1,s + rts + +* Read and process screen descriptor +screendesc + pshs a,b + bsr GIFgetword + std swidth First word is screen width in pixels + bsr GIFgetword + std sheight Next is screen height in pixels + lbsr I_GetByte This is bit-mapped + lbcs _error Bit 7: T= global map follows + tfr a,b Bits 6:5:4: number bits of "color resolution" - 1 + andb #7 Bits 2:1:0: Number of bits per pixel - 1 + incb (Determines size of color map) + stb pixel + tfr a,b + sex + sta domap Top bit is true if global color map follows + lbsr I_GetByte + lbcs _error + sta background + lbsr I_GetByte + lbcs _error + tsta + lbne E$Format + puls a,b,pc + +GIFgetword + lbsr I_GetByte + lbcs _error + tfr a,b + lbsr I_GetByte + lbcs _error + rts + +* Signature: scan input to find "GIF###", the GIF signature string, +* where ### is two digits followed by a lowercase letter, e.g. +* '87a' +sigsub + lbsr I_GetByte + lbcs _error + rts + +signature + pshs a,b +Sig0 + bsr sigsub +Sig1 + cmpa #'G Search for "GIF" + bne Sig0 + bsr sigsub + cmpa #'I + bne Sig1 + bsr sigsub + cmpa #'F + bne Sig1 + clrb +Sig2 + bsr sigsub Get two digits + cmpa #'0 + blo Sig1 + cmpa #'9 + bhi Sig1 + comb + bne Sig2 + bsr sigsub and one lowercase letter + cmpa #'a + blo Sig1 + cmpa #'z + bhi Sig1 + puls a,b,pc + + +* +*LZW decode subs. +* + vsect dp +codelimit rmb 2 Point at which we must switch code sizes. + endsect + +* Miscellaneous initialization +lzwinit + pshs a,b,x + clr <packsiz + clr <numbits + puls a,b,x,pc + +* Initialize the decode table +* +clrtable + pshs a,b,x,y + ldx giftable Get start of table + lda mincode + lbsr powertwo + pshs y + tfr d,y + clra + clrb +clrloop + sta ,x+ Roots have 0 for pointer, themselves for suffix + std ,x++ + incb + leay -1,y + bne clrloop + puls y + stx clrcode + leax 3,x + stx endcode + leax 3,x + tfr x,u Set up nextentry pointer in U + lda mincode + sta codesize Pretend we were doing "mincode". + lbsr setlimit Bump to next codesize. + puls a,b,x,y,pc + + vsect dp +packptr rmb 2 +packsiz rmb 1 + endsect +* Return next byte from file +nextbyte + pshs x + tst packsiz + bne nextbyte1 + lbsr getpacket + sta packsiz + leax altbuff,y + stx packptr +nextbyte1 + dec packsiz + ldx packptr + lda ,x+ + stx packptr + puls x,pc + + vsect dp +numbits rmb 1 Number of bits in bit buffer +bitbuff rmb 3 Buffer bits from file here +codemask rmb 2 Mask off just codesize bits. + endsect +* Return next token from file +nexttoken + pshs d + ldb numbits First, fill bitbuffer with enough bits to make up codesize + bra nexttokst +nexttokloop + ldx bitbuff Move other 16 bits forward. + stx bitbuff+1 + bsr nextbyte Get 8 more bits + sta bitbuff + addb #8 Increase bit count. +nexttokst + cmpb codesize + blo nexttokloop + stb numbits + cmpb #17 Do we have to deal with three bytes? + blo nexttok2 No, 16 or fewer bits, so just deal with two. + ldb #20 + subb numbits First, we shift until we get to bit #20. + clra + tfr d,x + ldd bitbuff We keep first two bytes in D, leave 3rd one in place. +nexttok31 + lsra Analysis shows that we are never past bit 19, so we will + rorb always have to process this loop at least once. + ror bitbuff+2 + leax -1,x + bne nexttok31 + tfr b,a Now, the first bit of the token we want is out of the first + ldb bitbuff+2 byte, so we're down to two bytes. + lsra + rorb Since we start with the least sig bit in bit #20, and we want it + lsra in bit #24, we must shift exactly 4 times. + rorb + lsra + rorb + lsra + rorb + bra nexttok10 Now we have our token. +nexttok2 + cmpb #9 Do we have to deal with two bytes? + blo nexttok1 + ldb #16 + subb numbits + clra + tfr d,x + ldd bitbuff + stx -2,s Test X for zero. + beq nexttok10 +nexttok21 + lsra + rorb + leax -1,x + bne nexttok21 + bra nexttok10 +nexttok1 + ldb bitbuff + lda #8 + suba numbits + beq nexttok10 +nexttok11 + lsrb + deca + bne nexttok11 +nexttok10 + anda codemask + andb codemask+1 + ldx <giftable + leax d,x + leax d,x + leax d,x + ldb numbits + subb codesize + stb numbits + puls d,pc + +outcode + pshs a,b,x,y,u + ldu <gifstack + cmpx 6,s U is on the stack. + lbhi E$Format If the code is too large, report a format error + beq outcode1 + bsr outcsub If it's in the table, process it. + bra outcode2 +outcode1 + ldx lastcode If it's not in the table, then it is the last code + bsr outcsub followed by the first color of the last code. + lda firstcolor + lbsr gifoutpix +outcode2 + puls a,b,x,y,u,pc + +outcsub + pshs y + ldy #0000 +outc1 + lda 2,x + leay 1,y + pshu a + ldx ,x + bne outc1 + tfr y,x Put the count in X + puls y + + sta firstcolor Now we know the first color, so store it. + +outc2 + pulu a + lbsr gifoutpix + leax -1,x + bne outc2 + rts + +* Add a code to the table +addcode + pshs a,b + puls a,b,pc + +setlimit + pshs a,b,x + lda codesize + cmpa #12 + bhs setlim1 + inca +setlim1 + sta codesize + lbsr powertwo + ldx giftable + leax d,x + leax d,x + leax d,x + stx codelimit + subd #1 + std <codemask + puls a,b,x,pc + + endsect