BBS: Inland Empire Archive Date: 12-27-92 (06:20) Number: 243 From: RICH GELDREICH Refer#: NONE To: ALL Recvd: NO Subj: Bload Compressor/2 Conf: (2) Quik_Bas
'Page 2 of ENCODE13.BAS begins here.
REDIM image(32000): DEF SEG = VARSEG(image(0))
BLOAD "coolfile.bci", VARPTR(image(0)) 'Load the compressed data.
PRINT "Press a key to decompress.": B$ = INPUT$(1): SCREEN 13
'Call the asm routine to decompress the image.
Decom13 VARSEG(image(0)), VARPTR(image(0)): B$ = INPUT$(1)
'Compresses a SCREEN 13 image to a BLOADable file. Use the ASM sub
'Decom13 to decompress the image back to the screen. This routine
'currently crawls, because I didn't optimize it that much.
'The entire palette is also saved to the compressed file,
SUB Compress13 (F$)
OPEN F$ FOR OUTPUT AS #1: CLOSE : OPEN F$ FOR BINARY AS #1
'Store the BLOAD header and image signature.
a$ = CHR$(&HFD) + CHR$(0) + CHR$(&HA0) + STRING$(4, 0) + "RG"
PUT #1, , a$
'Initialize a 4k disk output buffer
IOBuffer$ = SPACE$(4096): IOPointer = 1
CodePointer = 0: CodeCounter = 0: OrMask = 1: BitAccum = 0
'Write the screen's palette.
OUT &H3C7, 0: FOR a = 0 TO 767: WriteByte INP(&H3C9): NEXT
DoneFlag = False: xl = 0: yl = 0: xh = 319: yh = 199
xp = xl: yp = yl 'coordinate of next point to compress
InitRingBuffer 'clear the ring buffer
InitLZ77 'initialize the linked list pool
'prime the look ahead buffer
S = 0: R = BufferSize - MaxMatch
FOR LookAheadLength = 0 TO MaxMatch - 1
IF DoneFlag THEN
EXIT FOR
ELSE
RingBuffer(R + LookAheadLength) = GetPixel
END IF
NEXT
'find first string
FindString R
DO
'if match too small(less than 3 chars), the just output
'a single character
IF Match.Length <= Threshold THEN
OutputChar RingBuffer(R): Last.Match.Length = 1
ELSE
'output a string match token
Last.Match.Length = Match.Length
'Send the match's distance, instead of its position in
'the ring buffer, because the decompressor is not using a
'ring buffer to store the decompressed data.
Match.Distance = (R - Match.Position) AND (BufferSize - 1)
OutputMatch
END IF
'prime the look ahead buffer with more characters
FOR a = 0 TO Last.Match.Length - 1
IF DoneFlag THEN EXIT FOR 'exit this loop if no more chars
'delete string at S, then store a new char at S
DeleteString S: RingBuffer(S) = GetPixel
'keep a "ghost buffer" at the end of the ring buffer to
'avoid using a logical AND on all of our buffer pointers
IF S < (MaxMatch - 1) THEN
RingBuffer(S + BufferSize) = RingBuffer(S)
END IF
S = (S + 1) AND (BufferSize - 1)
R = (R + 1) AND (BufferSize - 1)
'if not last time through loop then just add string to the
'linked list pool, otherwise add it and find a match
'(this could be optimized so the IF/THEN conditional is
'removed from inside this loop)
IF a = (Last.Match.Length - 1) THEN
FindString R
ELSE
MakeString R
END IF
NEXT
FOR a = a TO Last.Match.Length - 1
'this loop is active when no more characters are available
'from the input stream
'Kill string at S, not sure if this is needed because
'we're not storing any characters in its place. I see
'no reason to do it, but this is one of those little
'quirks that all LZSS implementations I've seen have... ?
DeleteString S
S = (S + 1) AND (BufferSize - 1)
R = (R + 1) AND (BufferSize - 1)
LookAheadLength = LookAheadLength - 1
IF LookAheadLength THEN
IF a = (Last.Match.Length - 1) THEN
FindString R
ELSE
'Continued on page 3
--- MsgToss 2.0b
* Origin: Computer Co-Op - Voorhees, NJ | Ted Hare (1:266/29)

Books at Amazon:
Back to BASIC: The History, Corruption, and Future of the Language
Hackers: Heroes of the Computer Revolution (including Tiny BASIC)
Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution
The Advent of the Algorithm: The Idea that Rules the World
Moths in the Machine: The Power and Perils of Programming
Mastering Visual Basic .NET