Skip to content

Commit

Permalink
add fallback zlib/glib support on Octave via file-based zip/unzip
Browse files Browse the repository at this point in the history
  • Loading branch information
fangq committed Oct 27, 2023
1 parent 7ab1b6e commit ce3c0a0
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 4 deletions.
1 change: 1 addition & 0 deletions Contents.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
% match_bracket - [endpos, maxlevel] = match_bracket(str,startpos,brackets)
% mergestruct - s=mergestruct(s1,s2)
% nestbracket2dim - [dims, isndarray, maxlevel, count] = nestbracket2dim(str,brackets)
% octavezz - output = octavezz(input, iscompress, zipmethod)
% savebj - bjd=savebj(obj)
% savejd - savejd(rootname, obj, outputfile)
% savejson - json=savejson(obj)
Expand Down
1 change: 1 addition & 0 deletions INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Compression and Decompression
lzmaencode
zlibdecode
zlibencode
octavezz
Helper Functions
decodevarname
encodevarname
Expand Down
4 changes: 3 additions & 1 deletion gzipdecode.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
end
return;
elseif(isoctavemesh)
error('You must install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
warning('You are recommended to install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
[varargout{1:nargout}]=octavezz(varargin{1}, 0, 'gzip');
return;
end
error(javachk('jvm'));

Expand Down
4 changes: 3 additions & 1 deletion gzipencode.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
[varargout{1:nargout}]=zmat(varargin{1},1,'gzip');
return;
elseif(isoctavemesh)
error('You must install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
warning('You are recommended to install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
[varargout{1:nargout}]=octavezz(varargin{1}, 1, 'gzip');
return;
end

error(javachk('jvm'));
Expand Down
134 changes: 134 additions & 0 deletions octavezz.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
function varargout=octavezz(data, iscompress, zipmethod)
%
% output = octavezz(input, iscompress, zipmethod)
% or
% [output, info] = octavezz(input, iscompress, zipmethod)
% unzipdata = octavezz(zipdata, info)
%
% Compress or decompress zlib and gzip memory buffers using zip/unzip/gzip/gunzip on Octave
% in case ZMat toolbox (http:/NeuroJSON/zmat) was not installed (ZMat will be much faster)
%
% Copyright (c) 2023, Qianqian Fang (q.fang <at> neu.edu)
%
% input:
% input: the input data (can be either compressed or before compression),
% can be a string, a numerical vector or array
% iscompress: (optional) if iscompress is 1, zmat compresses/encodes the input,
% if 0, it decompresses/decodes the input. Default value is 1.
%
% if iscompress is set to a negative integer, (-iscompress) specifies
% the compression level. For zlib/gzip, default level is 6 (1-9); for
% lzma/lzip, default level is 5 (1-9); for lz4hc, default level is 8 (1-16).
% the default compression level is used if iscompress is set to 1.
%
% zmat removes the trailing newline when iscompress=2 and method='base64'
% all newlines are kept when iscompress=3 and method='base64'
%
% if one defines iscompress as the info struct (2nd output of zmat), zmat
% will perform a decoding/decompression operation and recover the original
% input using the info stored in the info structure.
% method: (optional) compression method, only the below two methods are supported
% 'zlib': zlib/zip based data compression (default)
% 'gzip': gzip formatted data compression
%
% output:
% output: the decompressed byte stream stored in a uint8 vector; if info is
% given, output will restore the original data's type and dimensions
% info: (optional) a struct storing additional info regarding the input data, may have
% 'type': the class of the input array
% 'size': the dimensions of the input array
% 'byte': the number of bytes per element in the input array
% 'method': a copy of the 3rd input indicating the encoding method
% 'status': the zlib/lzma/lz4 compression/decompression function return value,
% including potential error codes; see documentation of the respective
% libraries for details
% 'level': a copy of the iscompress flag; if non-zero, specifying compression
% level, see above
%
% examples:
% [ss,info]=octavezz(ones(10))
% orig=octavezz(ss,info)
%
% license:
% BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
%
% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%

if(nargin < 1)
fprintf(1,'Format: output = octavezz(data, iscompress, zipmethod)\n');
return;
end

if(nargin < 2)
iscompress=1;
end

if(nargin < 3)
zipmethod='zlib';
end

if(isstruct(iscompress))
inputinfo = iscompress;
iscompress = 0;
end

fname=tempname;
tmpfile=fname;
outputfile=fname;

suff=struct('zlib', '.zip', 'gzip', '.gz');

if(~isfield(suff,zipmethod))
error('zipmethod is not supported')
end

if(~iscompress)
tmpfile=[fname suff.(zipmethod)];
end

fd=fopen(tmpfile,'wb');
if(~fd)
error('unable to create temporary file');
end
fwrite(fd, data, 'uint8');
fclose(fd);

if(iscompress)
outputfile=[fname suff.(zipmethod)];
end

if(~iscompress)
if(strcmp(zipmethod, 'zlib'))
outputfile=unzip(tmpfile, tempdir);
outputfile=[tempdir filesep outputfile{1}];
elseif(strcmp(zipmethod, 'gzip'))
gunzip(tmpfile);
end
else
if(strcmp(zipmethod, 'zlib'))
zip(outputfile, tmpfile);
elseif(strcmp(zipmethod, 'gzip'))
gzip(tmpfile);
end
end

fd=fopen(outputfile, 'rb');
if(~fd)
error('failed to unzip buffer');
end
varargout{1}=fread(fd, [1 inf], 'uint8');
fclose(fd);

if(nargout>1)
varargout{2}=struct('type',class(data),'size',size(data),'method',zipmethod,'status',0, 'level', iscompress);
end

if (exist('inputinfo', 'var') && isfield(inputinfo, 'type'))
if(strcmp(inputinfo.type,'logical'))
varargout{1} = logical(varargout{1});
else
varargout{1} = typecast(varargout{1}, inputinfo.type);
end
varargout{1} = reshape(varargout{1}, inputinfo.size);
end
4 changes: 3 additions & 1 deletion zlibdecode.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
end
return;
elseif(isoctavemesh)
error('You must install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
warning('You are recommended to install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
[varargout{1:nargout}]=octavezz(varargin{1}, 0, 'zlib');
return;
end
error(javachk('jvm'));

Expand Down
4 changes: 3 additions & 1 deletion zlibencode.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
[varargout{1:nargout}]=zmat(varargin{1},1,'zlib');
return;
elseif(isoctavemesh)
error('You must install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
warning('You are recommended to install the ZMat toolbox (http:/NeuroJSON/zmat) to use this function in Octave');
[varargout{1:nargout}]=octavezz(varargin{1}, 1, 'zlib');
return;
end

error(javachk('jvm'));
Expand Down

0 comments on commit ce3c0a0

Please sign in to comment.