📄 lzw2norm.m
字号:
function [output,table] = lzw2norm (vector, maxTableSize, restartTable)%LZW2NORM LZW Data Compression (decoder)% For vectors, LZW2NORM(X) is the uncompressed vector of X using the LZW algorithm.% [...,T] = LZW2NORM(X) returns also the table that the algorithm produces.%% For matrices, X(:) is used as input.%% maxTableSize can be used to set a maximum length of the table. Default% is 4096 entries, use Inf for unlimited. Usual sizes are 12, 14 and 16% bits.%% If restartTable is specified, then the table is flushed when it reaches% its maximum size and a new table is built.%% Input must be of uint16 type, while the output is a uint8.% Table is a cell array, each element containig the corresponding code.%% % How it decodes:%% Read OLD_CODE% output OLD_CODE% CHARACTER = OLD_CODE% WHILE there are still input characters DO% Read NEW_CODE% IF NEW_CODE is not in the translation table THEN% STRING = get translation of OLD_CODE% STRING = STRING+CHARACTER% ELSE% STRING = get translation of NEW_CODE% END of IF% output STRING% CHARACTER = first character in STRING% add translation of OLD_CODE + CHARACTER to the translation table% OLD_CODE = NEW_CODE% END of WHILE% Ensure to handle uint8 input vector and convert% to a rowif ~isa(vector,'uint16'), error('input argument must be a uint16 vector')endvector = vector(:)';if (nargin < 2) maxTableSize = 4096; restartTable = 0;end;if (nargin < 3) restartTable = 0;end; function code = findCode(lastCode, c) % Look up code value % if (isempty(lastCode)) % fprintf('findCode: ---- + %02x = ', c); % else % fprintf('findCode: %04x + %02x = ', lastCode, c); % end; if (isempty(lastCode)) code = c+1; %fprintf('%04x\n', code); return; else ii = table.codes(lastCode).prefix; jj = find([table.codes(ii).c] == c); code = ii(jj); % if (isempty(code)) % fprintf('----\n'); % else % fprintf('%04x\n', code); % end; return; end; end function [] = addCode(lastCode, c) % Add a new code to the table e.c = c; % NB using variable in parent to avoid allocation cost e.lastCode = lastCode; e.prefix = []; e.codeLength = table.codes(lastCode).codeLength + 1; table.codes(table.nextCode) = e; table.codes(lastCode).prefix = [table.codes(lastCode).prefix table.nextCode]; table.nextCode = table.nextCode + 1; % if (isempty(lastCode)) % fprintf('addCode : ---- + %02x = %04x\n', c, table.nextCode-1); % else % fprintf('addCode : %04x + %02x = %04x\n', lastCode, c, table.nextCode-1); % end; end function str = getCode(code) % Output the string for a code l = table.codes(code).codeLength; str = zeros(1, l); for ii = l:-1:1 str(ii) = table.codes(code).c; code = table.codes(code).lastCode; end; end function [] = newTable % Build the initial table consisting of all codes of length 1. The strings % are stored as prefixCode + character, so that testing is very quick. To % speed up searching, we store a list of codes that each code is the prefix % for. e.c = 0; e.lastCode = -1; e.prefix = []; e.codeLength = 1; table.nextCode = 2; if (~isinf(maxTableSize)) table.codes(1:maxTableSize) = e; % Pre-allocate for speed else table.codes(1:65536) = e; % Pre-allocate for speed end; for c = 1:255 e.c = c; e.lastCode = -1; e.prefix = []; e.codeLength = 1; table.codes(table.nextCode) = e; table.nextCode = table.nextCode + 1; end; end%% Main loop%e.c = 0;e.lastCode = -1;e.prefix = [];e.codeLength = 1;newTable;output = zeros(1, 3*length(vector), 'uint8'); % assume compression of 33%outputIndex = 1;lastCode = vector(1);output(outputIndex) = table.codes(vector(1)).c;outputIndex = outputIndex + 1;character = table.codes(vector(1)).c;tic;for vectorIndex=2:length(vector), % if mod(vectorIndex, 1000) == 0 % fprintf('Index: %5d, Time %.1fs, Table Length %4d, Complete %.1f%%\n', outputIndex, toc, table.nextCode-1, vectorIndex/length(vector)*100); %*ceil(log2(size(table, 2)))/8); % tic; % end; element = vector(vectorIndex); if (element >= table.nextCode) % add codes not in table, a special case. str = [getCode(lastCode) character]; else, str = getCode(element); end output(outputIndex + (0:length(str)-1)) = str; outputIndex = outputIndex + length(str); if ((length(output)-outputIndex) < 1.5*(length(vector)-vectorIndex)) output = [output zeros(1, 3*(length(vector)-vectorIndex), 'uint8')]; end; if (length(str) < 1) keyboard; end; character = str(1); if (table.nextCode <= maxTableSize) addCode(lastCode, character); if (restartTable && table.nextCode == maxTableSize+1) % fprintf('New table\n'); newTable; end; end; lastCode = element;end;output = output(1:outputIndex-1);table.codes = table.codes(1:table.nextCode-1);end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -