| | 171 | |
|---|
| | 172 | ops_boolean_t ops_write_compressed(const unsigned char *data, |
|---|
| | 173 | const unsigned int len, |
|---|
| | 174 | ops_create_info_t *cinfo) |
|---|
| | 175 | { |
|---|
| | 176 | int r=0; |
|---|
| | 177 | int sz_in=0; |
|---|
| | 178 | int sz_out=0; |
|---|
| | 179 | compress_arg_t* compress=ops_mallocz(sizeof *compress); |
|---|
| | 180 | |
|---|
| | 181 | // compress the data |
|---|
| | 182 | const int level=Z_DEFAULT_COMPRESSION; // \todo allow varying levels |
|---|
| | 183 | compress->stream.zalloc=Z_NULL; |
|---|
| | 184 | compress->stream.zfree=Z_NULL; |
|---|
| | 185 | compress->stream.opaque=NULL; |
|---|
| | 186 | |
|---|
| | 187 | // all other fields set to zero by use of ops_mallocz |
|---|
| | 188 | |
|---|
| | 189 | if (deflateInit(&compress->stream,level) != Z_OK) |
|---|
| | 190 | { |
|---|
| | 191 | // can't initialise |
|---|
| | 192 | assert(0); |
|---|
| | 193 | } |
|---|
| | 194 | |
|---|
| | 195 | // do necessary transformation |
|---|
| | 196 | // copy input to maintain const'ness of src |
|---|
| | 197 | assert(compress->src==NULL); |
|---|
| | 198 | assert(compress->dst==NULL); |
|---|
| | 199 | |
|---|
| | 200 | sz_in=len * sizeof (unsigned char); |
|---|
| | 201 | sz_out= (sz_in * 1.01) + 12; // from zlib webpage |
|---|
| | 202 | compress->src=ops_mallocz(sz_in); |
|---|
| | 203 | compress->dst=ops_mallocz(sz_out); |
|---|
| | 204 | memcpy(compress->src,data,len); |
|---|
| | 205 | |
|---|
| | 206 | // setup stream |
|---|
| | 207 | compress->stream.next_in=compress->src; |
|---|
| | 208 | compress->stream.avail_in=sz_in; |
|---|
| | 209 | compress->stream.total_in=0; |
|---|
| | 210 | |
|---|
| | 211 | compress->stream.next_out=compress->dst; |
|---|
| | 212 | compress->stream.avail_out=sz_out; |
|---|
| | 213 | compress->stream.total_out=0; |
|---|
| | 214 | |
|---|
| | 215 | r=deflate(&compress->stream, Z_FINISH); |
|---|
| | 216 | assert(r==Z_STREAM_END); // need to loop if not |
|---|
| | 217 | |
|---|
| | 218 | // write it out |
|---|
| | 219 | return (ops_write_ptag(OPS_PTAG_CT_COMPRESSED, cinfo) |
|---|
| | 220 | && ops_write_length(1+compress->stream.total_out, cinfo) |
|---|
| | 221 | && ops_write_scalar(OPS_C_ZLIB,1,cinfo) |
|---|
| | 222 | && ops_write(compress->dst, compress->stream.total_out,cinfo)); |
|---|
| | 223 | } |
|---|
| | 224 | |
|---|
| | 225 | // EOF |
|---|