Hey all, I'm working on some simple compression and decompression routines to be used on teh eZ80 and Z80 calcs. First up is LZ77 compression and I know KermM mentioned interest in writing a computer-side compression program.


I will be editing this first post with actual Z80 and eZ80 routines as I make them

So the pseudo-code for LZ77 compression:

Code:

;Variables:
;  write_head points to the start of the output data and auto-increments when used
;  read_head points to the start of the input


   find the byte that occurs least frequently in the data. This will be our "escape byte."
#if you need to allocate RAM for the output data, allocate a number of bytes equal to 1+original size + number of occurences of the escape byte in the original data.


   escape byte -> (write_head)     #remember this auto increments write_head
while read_head != eof
   search for the largest matching sub-string (up to 259 bytes long)
   If match< (5+number of occurences of the escape byte)
      escape_byte ->  (write_head)
      match_size-4 -> (write_head)
      match_offset_LSB ->(write_head)
      match_offset_MSB ->(write_head)
      read_head+match_size -> read_head
   ELSE
      (read_head) -> temp
      read_head++
      temp -> (write_head)
      if temp = escape_byte
         0 -> (write_head)

Some notes:
Searching for the largest matching substring should start at most 65535 bytes before the current read_head or the beginning of the source data (whichever is smaller).
Valid matches must be 259 bytes or less and this is match_size
match_offset is the number bytes before read_head where the match occurs


Code:

lz77_decompress:
;;Inputs: HL points to compressed data
;;        DE points to where the data is decompressed to
;;        BC is the size of the compressed data
;;        A is the escape byte
    cp (hl) \ jr z,esc \ ldi \ jp pe,loop \ ret
.esc
    push af
    inc hl
    ld a,(hl)
    or a
    jr nz,$+5
    ld (de),a
    jr a
    push bc
    inc hl
    ld c,(hl)
    inc hl
    ld b,(hl)
    push hl
    ld h,d
    ld l,e
    sbc hl,bc
    add a,4
    ld c,a
    ld a,0
    rla
    ld b,a
    ldir
    pop hl
    pop bc
    dec bc
    dec bc
.a
    pop af
    dec bc
    cpi
    jp pe,lz77_decompress
    ret
Just to make sure, is this a canonical LZ77 routine compatible with existing LZ77 implementations (ie, following the original documented form from Ziv and Lempel)? If so, that will significantly simplify the computer-side implementation.
I'm not actually sure and the material is too dense for my sleepy brain.

Basically, my proposed algorithm looks for matching substrings that occur previously in the input data and if a long enough match is found, it is recorded as simply a size and pointer. I use some specified byte to indicate one of these size+pointers, and the byte chosen is one which occurs least frequently in the source data. In the event that the frequency that this "escape byte" occurs in the source data, it is encoded as just 'escape_byte,0'.

By doing this, only the least frequent byte can be encoded to a larger size while everything else is encoded as the same size or smaller.
What algorithm are you using for substring matching?
I am searching on the interval [source_start, read_head) (where read head is the location of the first byte that I am searching for a match). I use CPIR to locate a first byte match, then I compare consecutive bytes until the end of the search space, or a non-match. At this point, I compare sizes to a previously found size, if it is bigger, I store this as a tentative match.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement