LZ77

De GirinoWiki

LZ77 foi um dos algoritmos de compressão de dados desenvolvidos por Abraham Lempel e Jacob Ziv em 1977, juntamente com o outro algoritmo de compressão LZ78 publicado em 1978. Nos primeiros artigos publicados eles eram conhecidos por LZ1 e LZ2 respectivamente e só depois ganharam o ano de sua publicação em suas siglas[1].

O algoritmo LZ77 se baseia na utilização das partes que já foram lidas de de um arquivo como um dicionário, substituindo as próximas ocorrências das mesmas seqüências de caracteres pela posição (absoluta ou relativa) da sua última ocorrência. Para limitar o espaço de busca e de endereçamento necessário, as ocorrências anteriores são limitadas por uma "janela deslizante" (do inglês sliding window) que tem tamanho fixo e "desliza" sobre o arquivo, delimitando o início e fim da área onde serão buscadas as ocorrências anteriores. O tamanho desta janela é um dos fatores primordiais para se ajustar a performance desse algoritmo.

Tabela de conteúdo

[editar] Algoritmo

O algoritmo LZ77 é relativamente simples. Define-se inicialmente duas estruturas que serão usadas: A janela de procura, e o buffer de look-ahead (num tradução livre poderia ser chamado de buffer de pré-visualização). A janela representa as partes do arquivo que já foram lidos, enquanto o look-ahead representa o que ainda será lido e processado pelo algoritmo. Na prática, o look-ahead é preenchido de antemão com os próximos bytes a serem processados pelo compressor. A janela tem tamanho definido, e deve permitir que os dados sejam enfileirados dentro dela, eliminando os bytes mais antigos quando seu limite de tamanho é atingido. O buffer de look-ahead também tem tamanho definido, em geral dezenas de vezes menor que a janela.

De posse dessas estruturas verificamos a seqüência de caracteres atualmente presente no buffer, e qual o maior casamento de prefixo dessa seqüência dentro da janela (qual a maior seqüência da janela casa exatamente com o início da seqüência do buffer). Ao encontrar tal seqüência emitimos na saída a tupla (Spos,Stam,c) onde Spos é a posição da seqüência casada dentro da janela (contada em geral de traz para diante), Stam é o tamanho dessa seqüência, e c é o próximo caractere presente no buffer depois dessa seqüência. Este caractere c é comumente chamado de literal, ou caractere literal (do inglês literal character).

Transferimos então toda a seqüência casada e mais o caractere extra para a janela (chama-se esse processo de deslizamento a janela ou window slide em inglês), que tem seus elementos mais antigos removidos (caso esteja cheia). O buffer é preenchido com novos dados lidos do arquivo, e continuamos o processo até o final do arquivo.

No caso de não ser encontrado nenhum casamento dentro da janela, emite-se a tupla (0,0,c), indicando que houve um "casamento" de tamanho 0, e apenas o caractere c é transferido para o buffer.

O processo de descompressão é bem mais simples pois não precisa fazer nenhum tipo de casamento de padrão, basta copiar os caracteres indicados pela tupla, na quantidade indicada, para a saída e acrescentar o caractere c, repetindo o processo até o fim das tuplas. Por essa diferença grande entre complexidade de compressão e descompressão diz-se que o algoritmo LZ77 é um algoritmo de compressão assimétrico.

Note que o tamanho da janela e do buffer impactam diretamente na performance do compressor: quanto maior eles forem, melhor a compressão, mas também mais lenta ela fica. O tamanho dessas estruturas deve ser bem estudado quando da implementação desse algoritmo.

[editar] Exemplo

Abaixo ilustramos o algoritmo LZ77 com um exemplo da compressão da cadeia A_ASA_DA_CASA, usando janela de tamanho 8 e buffer de look-ahead de tamanho 4.

Janela Buffer Restante do arquivo Tupla emitida
A_AS A_DA_CASA (0,0,A)
A _ASA _DA_CASA (0,0,_)
A_ ASA_ DA_CASA (1,1,S)
A_AS A_DA _CASA (3,2,D)
A_ASA_D A_CA SA (2,2,C)
ASA_DA_C ASA (7,3,EOF)

Temos então 6 tuplas, cada tupla ocupa 15 bits (4 para a posição dentro da janela, 3 para o tamanho e 8 para o caractere no final), perfazendo 90 bits. Comparado com a cadeia original de 104 bits (13 bytes) a compressão não é muito boa, mas para arquivos maiores o tamanho da janela pode ser ajustado, assim como o tamanho do buffer, conseguindo taxas de compressão bem melhores.

[editar] Aplicações

Alguns programas e formatos de compressão de dados largamente utilizados usam este algoritmo, pois ao contrário do LZ78 e do LZW, seus parentes mais próximos, ele não estava coberto por patentes. A variante mais comum do LZ77 é conhecida como DEFLATE e combina o uso de LZ77 com o uso de Código Huffman. Entre os programas e formatos que usam LZ77 e DEFLATE temos:

  • O programa PKZIP e o formato de arquivos ZIP (além de todos os outros programas baseados nesse formato).
  • O programa gzip.
  • O formato de imagens PNG.

[editar] Exemplo de implementação

Ver artigo principal: LZ77 (python).

[editar] Referências

  1. SALOMON, David. Data Compression: The Complete Reference. 2.ed. Nova Iorque: Springer, 2000.

[editar] Bibliografia

[editar] Ver também

Ferramentas pessoais
Social Blogging
  • StumbleUpon
  • Adicionar aos Favoritos BlogBlogs
  • Adicionar esta página no Linkk
  • Add to Technorati Favorites
patrocinadores
Espaço comercial