Народ подскажите пожалуста модуль(если такой есть) в котором можно глянуть реализацию алгоритма lzw для gif на Перл ? А то весь CPAN перерыл , результата ноль. Конкретно интересует реализация чтения кодов переменной длинны из входного потока при декодировании.
Попытался сам реализовать алгоритм согласно его описаниюhttp://www.compression.ru/arctest/descript/lzw-gif.htm, но возникла такая проблема при обработке входного потока находится несколько кодов окончания потока данных . На всякий случай привожу код, может кто по конкретной ситуации поможет, заранее спасибо:Код | ##Decode grafic data from LZW ... { my $lzw_size; # текущий размер кода в битах my $ost; #остаток от предыдещего слова my $ost_size; #размер остатка от предыдущего слова my @table; #таблица кодов
sub decode_lzw_{ my $frame=$_[0]; #gif парсится и представляется в виде структуры данных собс-но $frame это указатель на соответствующий узел структуры my $word; #cлово фиксированного размера извлекаемое из кодированного потока my $word_size; # размер этого слова my $i=0; for(0..bytes::length($$frame{body})-1){ $lzw_size||=$$frame{lzw_size}+1; #используем сначала "код размера" указанный в потоке данных $word=vec($$frame{body},$_,8); # извлекаем слово $word_size=8; # размера 8-бит if(defined($ost_size)){ #если предыдущее слово обработано не полностью $word=($word<<$ost_size)|$ost; # добавляем остаток $word_size+=$ost_size; # и корректируем размер undef $ost_size; } while(($word_size-$word_size % $lzw_size)/$lzw_size > 0){ my $code=$word & 2**$lzw_size-1; #из полученного слова из младших разрядов извлекаем коды текущей длинны $word=$word>>$lzw_size; # выбрав код сдвигаем $word_size-=$lzw_size; if($code==2**$$frame{lzw_size}){ #здесь если встретили код очистки таблици делаем что необходимо... }elsif($code==2**$$frame{lzw_size}+1){ #сюда попадаем если конец потока данных }else{ #а сюда иначе $lzw_size++ if($code==2**$lzw_size-1); # если все коды длинны 2^текщая длинна исчерпаны $lzw_size=$$frame{lzw_size}+1 if($code==4095); #если мы исчерпали коды длинны 12-бит (за ним должен следовать код очистки) #ниже должно следовать процедура обрабатывающая полученный код } } if($word_size!=0){ # и наконец здесь сохраняем остаток для обработки его со следующим словом $ost=$word; $ost_size=$word_size; }
} }
}
|
ЗЫ Не судите строго, возможно, изобретаю велосипед, но тем не менее... |