Visual basic

Enhanced Quick Basic LZW compress and uncompress routine - this code is so old use at your own risk! I did however use this routine to store files in my special edit tool written for windows 95 called QEdit. Maybe some day I'll bring it back to life for Windows XP under vb .net




----------------------------------------------------------------------

CONST FALSE% = 0, TRUE% = NOT FALSE%
CONST PREFIX% = 0, SUFFIX% = 1, LINK% = 2
CONST MAXTABLE% = 4095
DECLARE SUB BLOCKCOPY (FROMSEG%, FROMADDR%, TOSEG%, TOADDR%, NUMbytes%)
DECLARE SUB CompletionPercent (MaxTaskValue&, CurTaskValue&, Position%)
DECLARE SUB Compload (FileSpec$, StartLoad&, MaxBytes&, Position%, FilePassword$, ProcessCode%, BytesLoaded&)
DECLARE SUB DeleteStr (Work$)
DECLARE SUB MEMaddr (Location&, Segment%, Offset%)
DECLARE FUNCTION CONVtoINT% (Digit&)
DECLARE FUNCTION MIDCHAR% (Work$, Position%)
DECLARE FUNCTION POWER2& (Digit%)

SUB Compload (FileSpec$, StartLoad&, MaxBytes&, Position%, FilePassword$, ProcessCode%, BytesLoaded&)
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'::: Subroutine, CompLoad - load a passed filespec into memory after   :::
':::   performing data uncompression techniques.                       :::
':::                                                                   :::
':::   INPUT: Filespec$, full disk, path and filename to load          :::
':::          StartLoad&, this is the actual memory address (Seg:offs) :::
':::            to begin loading the file to                           :::
':::          MaxBytes&, maximum bytes of memory available for loading :::
':::   OUTPUT: ProcessCode%, result code of the load process,          :::
':::            0-load ok, other-BASIC/PDQ error code                  :::
':::           FilePassWord$, password assigned to the file            :::
':::           BytesLoaded&, number of bytes loaded from the input file:::
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DIM WorkArray%(4700)  ' 9400 bytes
DIM SuffixValue(20) AS INTEGER, BINVALUE(16)     AS LONG
DIM CODETBL(4096, 2) AS INTEGER, HITTBL(4096)    AS INTEGER
DIM LASTbuffer AS STRING
DIM PrefixCandidate  AS INTEGER, SuffixCandidate AS INTEGER
DIM TABLEFULL        AS INTEGER, TABLETOP        AS INTEGER
DIM BitsPerWord      AS INTEGER  ' PACKING BITS (use 9 to 12 only)
DIM StoreValue       AS LONG, PackPointer        AS INTEGER

FOR X% = 0 TO 16: BINVALUE(X%) = POWER2&(X%): NEXT: ProcessCode% = 0
LastLoad& = StartLoad&: LastIndex& = StartIndex&: BytesLoaded& = FALSE%
Handle% = FREEFILE: BufSize& = 2048: OPEN FileSpec$ FOR BINARY AS Handle%
IF ERR = 75 THEN
   OPEN FileSpec$ FOR INPUT AS Handle%
END IF
IF ERR THEN ProcessCode% = ERR
Remaining& = LOF(Handle%): FileSize& = Remaining&
IF Remaining& > MaxBytes& THEN ProcessCode% = 7
DO WHILE Remaining& > 0
   IF Remaining& < BufSize& THEN BufSize& = Remaining&: EOFflag% = TRUE%
   Buffer$ = SPACE$(BufSize&): GET #Handle%, , Buffer$
   IF ERR THEN ProcessCode% = ERR
   IF ProcessCode% THEN EXIT DO
   Rec% = Rec% + 1

   IF Rec% = 1 THEN
      A$ = MID$(Buffer$, 3, 6)
      FOR X% = 1 TO 6
          PassWord$ = PassWord$ + CHR$(MIDCHAR%(A$, X%) - 128)
      NEXT: FilePassword$ = RTRIM$(PassWord$)
      Buffer$ = RIGHT$(Buffer$, LEN(Buffer$) - 8): BitsPerWord = 9
      GOSUB InitLZW
   ELSE
      IF CrLf% = 0 THEN ProcessCode% = 6
   END IF
   
    GOSUB DecompressLZW
    IF ProcessCode% THEN EXIT DO

    Buffer$ = LEFToff$ + Buffer$: DeleteStr LEFToff$
    DO WHILE LEN(Buffer$)
     B% = LEN(Buffer$)
     IF B% >= 80 OR (EOFflag% = TRUE% AND B% <= 80) THEN

        GOSUB DecompressPOLAND

        MEMaddr LastLoad&, MEMseg%, MEMoff%
        BLOCKCOPY VARSEG(C$), SADD(C$), MEMseg%, MEMoff%, LEN(C$)
        LastLoad& = LastLoad& + 80&
        IF LastLoad& + 80& - StartLoad& > MaxBytes& THEN
           ProcessCode% = 7: EXIT DO
        END IF
     ELSE
       LEFToff$ = Buffer$: DeleteStr Buffer$
     END IF
   LOOP

Remaining& = Remaining& - BufSize&
IF ProcessCode% THEN EXIT DO
LOOP
CLOSE Handle%: BytesLoaded& = LastLoad& - StartLoad&: EXIT SUB

InitLZW:
FOR I% = 0 TO MAXTABLE%
    HITTBL(I%) = FALSE%: CODETBL(I%, LINK%) = FALSE%
    IF I% > 255 THEN
       CODETBL(I%, PREFIX%) = FALSE%: CODETBL(I%, SUFFIX%) = FALSE%
    ELSE
       CODETBL(I%, PREFIX%) = -1: CODETBL(I%, SUFFIX%) = I%
    END IF
NEXT: TABLEFULL% = FALSE%: TABLETOP = 255: RETURN

DecompressLZW:
IF LEN(Buffer$) THEN
   Pointer% = 1
   IF Rec% = 1 THEN
      GOSUB GetIntValue: PrefixCandidate = INTVALUE%
   END IF
 DO
   GOSUB GetIntValue: Dummy% = INTVALUE%
   IF Dummy% = -1 THEN
      IF EOFflag% = FALSE% THEN
         CompByte& = CompByte& + Pointer%
         Buffer$ = SPACE$(MemPointer%)
         BLOCKCOPY VARSEG(WorkArray%(0)), VARPTR(WorkArray%(0)), VARSEG(Buffer$), SADD(Buffer$), MemPointer%
         MemPointer% = 0: EXIT DO
        ELSE
         A$ = Buffer$: DeleteStr Buffer$: GOSUB GetIntValue: Dummy% = INTVALUE%
         Buffer$ = A$: DeleteStr A$
         IF Dummy% = FALSE% THEN
            Buffer$ = SPACE$(MemPointer%)
            BLOCKCOPY VARSEG(WorkArray%(0)), VARPTR(WorkArray%(0)), VARSEG(Buffer$), SADD(Buffer$), MemPointer%
            MemPointer% = 0: EXIT DO
         END IF
      END IF
   END IF
   IF PrefixCandidate < 256 THEN
      BLOCKCOPY VARSEG(PrefixCandidate), VARPTR(PrefixCandidate), VARSEG(WorkArray%(0)), VARPTR(WorkArray%(0)) + MemPointer%, 1
      MemPointer% = MemPointer% + 1
   END IF
   SuffixCandidate = Dummy%

   IF SuffixCandidate > 255 THEN    ' compressed character?
    SUFFIXCOPY% = SuffixCandidate   ' save just in case we expand it
    '
    ' Handle special case when you need to expand an entry that you
    ' have not yet added to the table
    '
    IF TABLETOP + 1 = SuffixCandidate THEN
       InputValue% = PrefixCandidate: OutputStatus% = FALSE%
       ExpandValue% = SuffixCandidate: GOSUB EXPAND
       SuffixCandidate = ExpandValue%
       GOSUB ManageTable: FoundCode% = MANAGETBL%
       SuffixCandidate = SUFFIXCOPY%

       InputValue% = SuffixCandidate: OutputStatus% = TRUE%
       ExpandValue% = Dummy%: GOSUB EXPAND
       BLOCKCOPY VARSEG(Expanded$), SADD(Expanded$), VARSEG(WorkArray%(0)), VARPTR(WorkArray%(0)) + MemPointer%, LEN(Expanded$)
       MemPointer% = MemPointer% + LEN(Expanded$)
     ELSE
       InputValue% = SuffixCandidate: OutputStatus% = TRUE%
       ExpandValue% = SuffixCandidate: GOSUB EXPAND
       SuffixCandidate = ExpandValue%
       BLOCKCOPY VARSEG(Expanded$), SADD(Expanded$), VARSEG(WorkArray%(0)), VARPTR(WorkArray%(0)) + MemPointer%, LEN(Expanded$)
       MemPointer% = MemPointer% + LEN(Expanded$)
       GOSUB ManageTable: FoundCode% = MANAGETBL%
       SuffixCandidate = SUFFIXCOPY%
    END IF

   ELSE
      GOSUB ManageTable: FoundCode% = MANAGETBL%
   END IF

    IF TABLEFULL THEN
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' LZW ADAPTIVE RESET - Cleans out the compression tables and allows   '
    ' re-filling of the tables. This allows large files to be compressed  '
    ' and decompressed. BitsPerWord must be reset to 9 after this routine.'
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    GOSUB InitLZW: GOSUB ManageTable: FoundCode% = MANAGETBL%
   END IF

    SELECT CASE TABLETOP
       CASE IS < 511: BitsPerWord = 9
       CASE IS < 1023: BitsPerWord = 10
       CASE IS < 2047: BitsPerWord = 11
       CASE ELSE: BitsPerWord = 12
    END SELECT

   PrefixCandidate = SuffixCandidate
   IF Position% THEN
      IF Pointer% AND 100 THEN
         CompletionPercent FileSize&, FileSize& - (CompByte& + Pointer%), Position%
      END IF
   END IF
 LOOP
END IF
RETURN

GetIntValue:
 Flag% = FALSE%
 DO
   IF LEN(Buffer$) THEN
      IF Pointer% <= LEN(Buffer$) THEN
         UNPACK& = MIDCHAR%(Buffer$, Pointer%)
         Pointer% = Pointer% + 1
        ELSE
         INTVALUE% = -1: RETURN
      END IF
     ELSE
      UNPACK& = FALSE%
   END IF

   PackPointer = PackPointer + 8
   IF PackPointer > BitsPerWord - 1 THEN
      TOT& = (UNPACK& * BINVALUE(PackPointer - 8)) + StoreValue
      ACTUAL& = TOT& MOD BINVALUE(BitsPerWord)
      Flag% = TRUE%
      INTVALUE% = CONVtoINT%(ACTUAL&)
      StoreValue = TOT& \ BINVALUE(BitsPerWord)
      PackPointer = PackPointer - BitsPerWord
     ELSE
      StoreValue = (UNPACK& * BINVALUE(PackPointer - 8)) + StoreValue
   END IF
 LOOP UNTIL Flag% = TRUE%
RETURN

DecompressPOLAND:
BufferIN$ = Buffer$: C$ = ""
FOR Y% = 1 TO LEN(BufferIN$)
 CUR% = MIDCHAR%(BufferIN$, Y%)
 SELECT CASE CUR%
   CASE 249 '      repeat last line uncompression
     C$ = LASTbuffer$:  EXIT FOR
   CASE 250 '      repeat portion of last line uncompression
     Y% = Y% + 1: NMBRchars% = MIDCHAR%(BufferIN$, Y%)
     C$ = LEFT$(LASTbuffer$, NMBRchars%)
   CASE 251 '      process CRLF uncompression
     CrLf% = CrLf% + 1: EXIT FOR
   CASE 11 ' process duplicate character uncompression
    Y% = Y% + 1: NMBRchars% = MIDCHAR%(BufferIN$, Y%)
    Y% = Y% + 1: CHARvalue% = MIDCHAR%(BufferIN$, Y%)
    C$ = C$ + STRING$(NMBRchars%, CHARvalue%)
   CASE 9  ' process tab uncompression
    TABoff% = (LEN(C$) + 1) \ 8: TABchars% = ((TABoff% + 1) * 8) - LEN(C$)
    C$ = C$ + SPACE$(TABchars%)
   CASE ELSE
    C$ = C$ + CHR$(CUR%)
 END SELECT
 IF LEN(C$) = 80 THEN EXIT FOR
NEXT: LASTbuffer$ = C$
Buffer$ = MID$(BufferIN$, Y% + 1, LEN(BufferIN$)): DeleteStr BufferIN$
IF LEN(C$) > 100 THEN ProcessCode% = 6
RETURN

ManageTable:
    Found% = FALSE%: ENDOFLINKS% = FALSE%

    IF HITTBL(PrefixCandidate) THEN
       CURPTR% = HITTBL(PrefixCandidate)
       DO
          IF CODETBL(CURPTR%, PREFIX%) = PrefixCandidate AND CODETBL(CURPTR%, SUFFIX%) = SuffixCandidate THEN
                 Found% = TRUE%
          ELSE
             IF CODETBL(CURPTR%, LINK%) THEN
                CURPTR% = CODETBL(CURPTR%, LINK%)
             ELSE
                ENDOFLINKS% = TRUE%
             END IF
          END IF
       LOOP UNTIL Found% OR ENDOFLINKS%
    END IF

    IF Found% THEN
       MANAGETBL% = CURPTR%
      ELSE
      IF NOT TABLEFULL THEN
          '
          ' The next 3 lines inserts prefixcandidate-suffixcandidate combo
          ' into the next available entry in the table.
          '
          TABLETOP = TABLETOP + 1
          CODETBL(TABLETOP, PREFIX%) = PrefixCandidate
          CODETBL(TABLETOP, SUFFIX%) = SuffixCandidate

          IF TABLETOP = MAXTABLE% THEN TABLEFULL = TRUE%

          IF HITTBL(PrefixCandidate) = 0 THEN
             HITTBL(PrefixCandidate) = TABLETOP
          ELSE
             CODETBL(CURPTR%, LINK%) = TABLETOP
          END IF
         END IF
         MANAGETBL% = FALSE%
    END IF
RETURN

EXPAND:
  DeleteStr Expanded$: SUFFIXcount% = FALSE%
  IF InputValue% > 255 THEN  ' Compressed value>255
     Kprefix% = CODETBL(InputValue%, PREFIX%)
     KSUFFIX% = CODETBL(InputValue%, SUFFIX%)
     IF Kprefix% > 255 THEN    ' Get suffix values until prefix < 256
        DO WHILE Kprefix% > 255
           returned% = Kprefix%
           SUFFIXcount% = SUFFIXcount% + 1
           Kprefix% = CODETBL(returned%, PREFIX%)
           KRETURNED% = Kprefix%
           SuffixValue%(SUFFIXcount%) = CODETBL(returned%, SUFFIX%)
           IF SUFFIXcount% > 19 THEN ProcessCode% = 6: RETURN
        LOOP
        IF OutputStatus% THEN
           Expanded$ = Expanded$ + CHR$(Kprefix%)
           FOR A% = SUFFIXcount% TO 1 STEP -1
               Expanded$ = Expanded$ + CHR$(SuffixValue%(A%))
           NEXT
        END IF
     ELSE
        KRETURNED% = Kprefix%
        IF OutputStatus% THEN Expanded$ = Expanded$ + CHR$(Kprefix%)
     END IF
     IF OutputStatus% THEN Expanded$ = Expanded$ + CHR$(KSUFFIX%)
  ELSE
     KRETURNED% = InputValue%
  END IF
  ExpandValue% = KRETURNED%
RETURN

END SUB

----------------------------------------------------------------------


CONST FALSE% = 0, TRUE% = NOT FALSE%
CONST PREFIX% = 0, SUFFIX% = 1, LINK% = 2

DECLARE SUB BLOCKCOPY (FROMSEG%, FROMADDR%, TOSEG%, TOADDR%, NUMbytes%)
DECLARE SUB CompletionPercent (MaxTaskValue&, CurTaskValue&, Position%)
DECLARE SUB CompSave (FileSpec$, BeginAddress&, BytesToSave&, Position%, FilePassWord$, ProcessCode%, BytesSaved&)
DECLARE SUB MemAddr (Location&, Segment%, Offset%)
DECLARE FUNCTION ConvToLong& (Digit%)
DECLARE FUNCTION MIDCHAR% (Work$, Position%)
DECLARE FUNCTION POWER2& (Digit%)

SUB CompSave (FileSpec$, BeginAddress&, BytesToSave&, Position%, FilePassWord$, ProcessCode%, BytesSaved&)
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'::: Subroutine, Compsave - Save a range of memory specified  :::
':::  by input parameters to a LZW compressed file.           :::
':::                                                          :::
':::  INPUT: FileSpec$ - disk, path and filespec of save file :::
':::         StartSave& - Beginning full address value        :::
':::         BytesToSave& - Number of bytes to save to disk   :::
':::         Position% - Actual byte to print completion      :::
':::           percentage of the save task                    :::
':::         FilePassWord$ - password assigned to the file    :::
':::                                                          :::
':::  OUTPUT: ProcessCode% - 0=successful operation           :::
':::                         other=BASIC/PDQ error code       :::
':::          BytesSaved& - Number of bytes successfully saved:::
'::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DIM LastBuffer AS STRING
DIM CODETBL(4096, 2) AS INTEGER, HITTBL(4096)    AS INTEGER
DIM PREFIXCANDIDATE  AS INTEGER, SUFFIXCANDIDATE AS INTEGER
DIM TableFull        AS INTEGER, TableTop        AS INTEGER
DIM BitsPerWord      AS INTEGER  ' PACKING BITS (use 9 to 12 only)
DIM BINVALUE(16)     AS LONG, STOREvalue         AS LONG
DIM PACKpointer      AS INTEGER, StrBytes(80)    AS INTEGER
DIM WorkArea(960)    AS INTEGER
FOR X% = 0 TO 16: BINVALUE(X%) = POWER2&(X%): NEXT: MAXTABLE% = 255
ProcessCode% = 0: Handle% = FREEFILE: OPEN FileSpec$ FOR BINARY AS Handle%
IF ERR THEN ProcessCode% = ERR
BitsPerWord = 9: GOSUB LZWinit: MAXTABLE% = 4095: PassWord$ = ""
FOR X% = 1 TO 6
    IF X% > LEN(FilePassWord$) THEN
       PassWord$ = PassWord$ + " "
    ELSE
       PassWord$ = PassWord$ + CHR$(MIDCHAR%(FilePassWord$, X%) + 128)
    END IF
NEXT

A$ = "JP" + PassWord$: PUT Handle%, , A$
IF ERR THEN ProcessCode% = ERR

PACKpointer = FALSE%: STOREvalue = FALSE%
FOR SAV& = BeginAddress& TO BeginAddress& + BytesToSave& STEP 80

    IF ProcessCode% THEN GOTO ErrorCheckRoutine  ' Bail out

    Buffer$ = SPACE$(80): MemAddr SAV&, MemSeg%, MemOff%
    BLOCKCOPY MemSeg%, MemOff%, VARSEG(Buffer$), SADD(Buffer$), 80
       GOSUB PolandCompress: Pointer% = FALSE%
       IF SAV& = BeginAddress& THEN
          Pointer% = 1: PREFIXCANDIDATE = MIDCHAR%(Buffer$, Pointer%)
       END IF
       MemPointer% = FALSE%
       DO
        Pointer% = Pointer% + 1: SUFFIXCANDIDATE = MIDCHAR%(Buffer$, Pointer%)
        IF SUFFIXCANDIDATE = -1 THEN  ' End of data ????
           IF SAV& < BeginAddress& + BytesToSave& - 80 OR PREFIXCANDIDATE = -1 THEN
              IF STOREvalue > 0 AND PREFIXCANDIDATE = -1 THEN
                 PREFIXCANDIDATE = FALSE%: GOSUB PackLzw
              END IF
              TempBuffer$ = ""
              IF MemPointer% THEN
                 TempBuffer$ = SPACE$(MemPointer%)
                 BLOCKCOPY VARSEG(WorkArea%(0)), 0, VARSEG(TempBuffer$), SADD(TempBuffer$), MemPointer%
              END IF
              Buffer$ = TempBuffer$
              EXIT DO
           END IF
        END IF
        GOSUB ManageTable
        
        IF FOUNDcode% THEN
           PREFIXCANDIDATE = FOUNDcode%
        ELSE
           GOSUB PackLzw

           SELECT CASE TableTop
           ' Upper bit limit is 12 (4096) and the lower limit
           ' is 9 (521)
             CASE IS < 512: BitsPerWord = 9
             CASE IS < 1024: BitsPerWord = 10
             CASE IS < 2048: BitsPerWord = 11
             CASE ELSE: BitsPerWord = 12
           END SELECT

           IF TableFull THEN
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            ' LZW ADAPTIVE RESET - Cleans out the compression          '
            ' tables and allows re-filling of the tables. This         '
            ' allows large files to be compressed and decompressed.    '
            ' BitsPerWord must not be reset to 9 after this routine.   '
            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            GOSUB LZWinit: GOSUB ManageTable
           END IF
           PREFIXCANDIDATE = SUFFIXCANDIDATE
        END IF
       LOOP

   Accum$ = Accum$ + Buffer$
   IF Position% THEN
      CompletionPercent BytesToSave&, BeginAddress& + BytesToSave& - SAV&, Position%
   END IF
   IF LEN(Accum$) > 4096 THEN
      PUT Handle%, , Accum$: Accum$ = ""
      IF ERR THEN ProcessCode% = ERR
   END IF
NEXT
IF ProcessCode% = 0 THEN PUT Handle%, , Accum$
IF ERR THEN ProcessCode% = ERR
GOTO ErrorCheckRoutine

LZWinit:
TableFull = FALSE%
FOR I% = 0 TO MAXTABLE%
    HITTBL(I%) = FALSE%: CODETBL(I%, LINK%) = FALSE%
    IF I% > 255 THEN
       CODETBL(I%, PREFIX%) = FALSE%: CODETBL(I%, SUFFIX%) = FALSE%
    ELSE
       CODETBL(I%, PREFIX%) = -1: CODETBL(I%, SUFFIX%) = I%
    END IF
NEXT
TableTop = 255: RETURN

PolandCompress:
NewBuffer$ = RTRIM$(Buffer$): StrLen% = LEN(NewBuffer$): New.Dat$ = ""
FOR X% = 1 TO StrLen%: StrBytes%(X%) = MIDCHAR%(NewBuffer$, X%): NEXT
IF StrLen% < 80 THEN StrBytes%(StrLen% + 1) = 251: StrLen% = StrLen% + 1
' Repeat compression from previous line?
ALLFLAG% = FALSE%: Repeat% = FALSE%: O% = FALSE%: Space.Count% = FALSE%
RptStart% = 1
IF LastBuffer$ = NewBuffer$ THEN
   ALLFLAG% = 1
  ELSEIF LEN(LastBuffer$) > 2 AND StrLen% > 2 THEN
   FOR X% = 1 TO StrLen%
    IF StrBytes%(X%) >= FALSE% THEN
     O% = O% + 1
     IF StrBytes%(X%) = MIDCHAR%(LastBuffer$, O%) THEN
        Repeat% = Repeat% + 1
       ELSE
        EXIT FOR
     END IF
    END IF
   NEXT
END IF

IF StrLen% > 2 AND ALLFLAG% <> FALSE% THEN
   FOR y% = 2 TO StrLen%: StrBytes%(y%) = -1: NEXT
   StrBytes%(1) = 249
  ELSEIF Repeat% > 2 THEN
   StrBytes%(1) = 250: StrBytes%(2) = Repeat%
   FOR y% = 3 TO X% - 1
    StrBytes%(y%) = -1
   NEXT: RptStart% = y% + 1
END IF

'  Process tab compression
FOR X% = 8 TO StrLen% STEP 8
    FOR y% = X% TO X% - 7 STEP -1
        Space.Count% = FALSE%
        IF StrBytes%(y%) = 32 THEN Space.Count% = Space.Count% + 1 ELSE EXIT FOR
    NEXT
    IF Space.Count% > 1 THEN
       StrBytes%(y% + 1) = 9
       FOR Z% = y% + 2 TO y% + Space.Count%
          StrBytes%(Z%) = -1
       NEXT
    END IF
NEXT
FOR X% = StrLen% TO 1 STEP -1  ' strip at end to beginning
    SELECT CASE StrBytes%(X%)
      CASE 9, 0
       StrBytes%(X%) = -1
      CASE ELSE
       EXIT FOR
    END SELECT
NEXT

'  Process duplicate characters more than 3 bytes in succession
DUPLICATES% = 1: LASTbyte% = FALSE%: FINDflag% = FALSE%
FOR X% = RptStart% TO StrLen%
   IF LASTbyte% > 0 THEN
    FINDflag% = FALSE%
    IF StrBytes%(X%) = LASTbyte% THEN FINDflag% = 1
    IF FINDflag% AND X% <> StrLen% THEN
       DUPLICATES% = DUPLICATES% + 1
      ELSE
       IF DUPLICATES% > 3 THEN
          IF FINDflag% AND X% = StrLen% THEN DUPLICATES% = DUPLICATES% + 1: X% = X% + 1
          StrBytes%(X% - DUPLICATES%) = 11
          StrBytes%(X% + 1 - DUPLICATES%) = DUPLICATES%
          StrBytes%(X% + 2 - DUPLICATES%) = LASTbyte%
          FOR y% = X% + 3 - DUPLICATES% TO X% - 1
            StrBytes%(y%) = -1
          NEXT
       END IF
       DUPLICATES% = 1
    END IF
   END IF
   IF X% < StrLen% THEN
      IF StrBytes%(X%) > 0 THEN LASTbyte% = StrBytes%(X%)
   END IF
NEXT
FOR X% = 1 TO StrLen%
   IF StrBytes%(X%) >= FALSE% THEN New.Dat$ = New.Dat$ + CHR$(StrBytes%(X%))
NEXT
Buffer$ = New.Dat$: LastBuffer$ = NewBuffer$: RETURN

ManageTable:
Found% = FALSE%: ENDOFLINKS% = FALSE%: CURPTR% = FALSE%
IF HITTBL(PREFIXCANDIDATE) THEN
   CURPTR% = HITTBL(PREFIXCANDIDATE)
   DO
    IF CODETBL(CURPTR%, PREFIX%) = PREFIXCANDIDATE AND CODETBL(CURPTR%, SUFFIX%) = SUFFIXCANDIDATE THEN
       Found% = TRUE%
    ELSE
       IF CODETBL(CURPTR%, LINK%) THEN
          CURPTR% = CODETBL(CURPTR%, LINK%)
       ELSE
          ENDOFLINKS% = TRUE%
       END IF
    END IF
   LOOP UNTIL Found% OR ENDOFLINKS%
END IF

IF Found% THEN
   FOUNDcode% = CURPTR%
ELSE
   IF NOT TableFull THEN
      TableTop = TableTop + 1: CODETBL(TableTop, PREFIX%) = PREFIXCANDIDATE
      CODETBL(TableTop, SUFFIX%) = SUFFIXCANDIDATE
      IF TableTop = MAXTABLE% THEN TableFull = TRUE%
      IF HITTBL(PREFIXCANDIDATE) = 0 THEN
         HITTBL(PREFIXCANDIDATE) = TableTop
      ELSE
         CODETBL(CURPTR%, LINK%) = TableTop
      END IF
   END IF
   FOUNDcode% = FALSE%
END IF
RETURN

PackLzw:
LONGint& = ConvToLong&(PREFIXCANDIDATE)
Packed$ = "": PACKpointer = PACKpointer + BitsPerWord
IF PACKpointer > 7 THEN
   TOT& = LONGint& * BINVALUE(PACKpointer - BitsPerWord) + STOREvalue
   PACKpointer = PACKpointer - 8
   Packed$ = Packed$ + CHR$(TOT& MOD BINVALUE(8))
   STOREvalue = TOT& \ BINVALUE(8)

   IF PACKpointer > 7 THEN
      Packed$ = Packed$ + CHR$(STOREvalue MOD BINVALUE(8))
      PACKpointer = PACKpointer - 8: STOREvalue = STOREvalue \ BINVALUE(8)
   END IF
ELSE
   STOREvalue = LONGint&
END IF
A% = LEN(Packed$)
IF A% THEN
   BLOCKCOPY VARSEG(Packed$), SADD(Packed$), VARSEG(WorkArea%(0)), MemPointer%, A%
   MemPointer% = MemPointer% + A%
END IF
RETURN

ErrorCheckRoutine:
CLOSE Handle%: BytesSaved& = SAV& - BeginAddress& - 80
END SUB






To contact me, please (Author of this website) E-mail me at:
jep1965@gmail.com

This page last updated July 6 2008

Counter







Hosted by www.Geocities.ws

1