forked from NeuroJSON/jsonlab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
octavezmat.m
162 lines (141 loc) · 5.21 KB
/
octavezmat.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
function varargout = octavezmat(data, iscompress, zipmethod)
%
% output = octavezmat(input, iscompress, zipmethod)
% or
% [output, info] = octavezmat(input, iscompress, zipmethod)
% unzipdata = octavezmat(zipdata, info)
%
% Compress or decompress zlib and gzip memory buffers using zip/unzip/gzip/gunzip on Octave
% in case ZMat toolbox (http://github.com/NeuroJSON/zmat) was not installed (ZMat is much faster)
%
% Author: 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:
% NO_ZMAT=1 % by setting this flag to 1 in the caller or global workspace, octavezmat won't warn zmat is missing
% [ss,info]=octavezmat(ones(10))
% orig=octavezmat(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)
%
nowarning = getvarfrom({'caller', 'base'}, 'NO_ZMAT');
if (isempty(nowarning) || nowarning == 0)
warning('You are recommended to install ZMat (http://github.com/NeuroJSON/zmat) get much faster speed in Octave');
end
if (nargin < 1)
fprintf(1, 'Format: output = octavezmat(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
if (~(ischar(data) || islogical(data) || (isnumeric(data) && isreal(data))))
error('input must be a char, non-complex numeric or logical vector or N-D array');
end
if (ischar(data))
data = uint8(data);
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, typecast(data(:), 'uint8'), 'uint8');
fclose(fd);
if (iscompress)
outputfile = [fname suff.(zipmethod)];
end
if (~iscompress)
if (strcmp(zipmethod, 'zlib'))
outputfile = unzip(tmpfile, tempdir);
if ((exist('OCTAVE_VERSION', 'builtin') ~= 0))
outputfile = [tempdir filesep outputfile{1}];
else
outputfile = outputfile{1};
end
elseif (strcmp(zipmethod, 'gzip'))
gunzip(tmpfile);
end
else
if (strcmp(zipmethod, 'zlib'))
zip(outputfile, tmpfile);
elseif (strcmp(zipmethod, 'gzip'))
gzip(tmpfile);
end
end
if (exist(tmpfile, 'file'))
delete(tmpfile);
end
fd = fopen(outputfile, 'rb');
if (~fd)
error('failed to unzip buffer');
end
varargout{1} = fread(fd, [1 inf], 'uint8=>uint8');
fclose(fd);
if (exist(outputfile, 'file'))
delete(outputfile);
end
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