19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* fitblk.c: example of fitting compressed output to a specified size 29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Not copyrighted -- provided to the public domain 39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Version 1.1 25 November 2004 Mark Adler */ 49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Version history: 69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.0 24 Nov 2004 First version 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1.1 25 Nov 2004 Change deflateInit2() to deflateInit() 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Use fixed-size, stack-allocated raw buffers 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Simplify code moving compression to subroutines 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Use assert() for internal errors 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Add detailed description of approach 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Approach to just fitting a requested compressed size: 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fitblk performs three compression passes on a portion of the input 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project data in order to determine how much of that input will compress to 189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project nearly the requested output block size. The first pass generates 199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project enough deflate blocks to produce output to fill the requested 209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project output size plus a specfied excess amount (see the EXCESS define 219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project below). The last deflate block may go quite a bit past that, but 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project is discarded. The second pass decompresses and recompresses just 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the compressed data that fit in the requested plus excess sized 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buffer. The deflate process is terminated after that amount of 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project input, which is less than the amount consumed on the first pass. 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project The last deflate block of the result will be of a comparable size 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project to the final product, so that the header for that deflate block and 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the compression ratio for that block will be about the same as in 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the final product. The third compression pass decompresses the 309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project result of the second step, but only the compressed data up to the 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project requested size minus an amount to allow the compressed stream to 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project complete (see the MARGIN define below). That will result in a 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project final compressed stream whose length is less than or equal to the 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project requested size. Assuming sufficient input and a requested size 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project greater than a few hundred bytes, the shortfall will typically be 369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project less than ten bytes. 379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project If the input is short enough that the first compression completes 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project before filling the requested output size, then that compressed 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stream is return with no recompression. 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project EXCESS is chosen to be just greater than the shortfall seen in a 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project two pass approach similar to the above. That shortfall is due to 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the last deflate block compressing more efficiently with a smaller 459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project header on the second pass. EXCESS is set to be large enough so 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project that there is enough uncompressed data for the second pass to fill 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out the requested size, and small enough so that the final deflate 489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project block of the second pass will be close in size to the final deflate 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project block of the third and final pass. MARGIN is chosen to be just 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project large enough to assure that the final compression has enough room 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project to complete in all cases. 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h> 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdlib.h> 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <assert.h> 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h" 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define local static 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* print nastygram and leave */ 629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void quit(char *why) 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, "fitblk abort: %s\n", why); 659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project exit(1); 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define RAWLEN 4096 /* intermediate uncompressed buffer size */ 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* compress from file to def until provided buffer is full or end of 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project input reached; return last deflate() return value, or Z_ERRNO if 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project there was read error on the file */ 739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int partcompress(FILE *in, z_streamp def) 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret, flush; 769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char raw[RAWLEN]; 779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flush = Z_NO_FLUSH; 799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def->avail_in = fread(raw, 1, RAWLEN, in); 819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ferror(in)) 829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_ERRNO; 839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def->next_in = raw; 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (feof(in)) 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flush = Z_FINISH; 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflate(def, flush); 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (def->avail_out != 0 && flush == Z_NO_FLUSH); 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* recompress from inf's input to def's output; the input for inf and 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the output for def are set in those structures before calling; 949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return last deflate() return value, or Z_MEM_ERROR if inflate() 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project was not able to allocate enough memory when it needed to */ 969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal int recompress(z_streamp inf, z_streamp def) 979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret, flush; 999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char raw[RAWLEN]; 1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flush = Z_NO_FLUSH; 1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* decompress */ 1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf->avail_out = RAWLEN; 1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf->next_out = raw; 1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate(inf, Z_NO_FLUSH); 1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && 1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret != Z_NEED_DICT); 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == Z_MEM_ERROR) 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* compress what was decompresed until done or no room */ 1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def->avail_in = RAWLEN - inf->avail_out; 1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def->next_in = raw; 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (inf->avail_out != 0) 1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project flush = Z_FINISH; 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflate(def, flush); 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (ret != Z_STREAM_END && def->avail_out != 0); 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define EXCESS 256 /* empirically determined stream overage */ 1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define MARGIN 8 /* amount to back off for completion */ 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* compress from stdin to fixed-size block on stdout */ 1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint main(int argc, char **argv) 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; /* return code */ 1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned size; /* requested fixed output block size */ 1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned have; /* bytes written by deflate() call */ 1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *blk; /* intermediate and final stream */ 1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char *tmp; /* close to desired size stream */ 1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project z_stream def, inf; /* zlib deflate and inflate states */ 1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get requested output size */ 1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (argc != 2) 1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("need one argument: size of output block"); 1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = strtol(argv[1], argv + 1, 10); 1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (argv[1][0] != 0) 1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("argument must be a number"); 1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret < 8) /* 8 is minimum zlib stream size */ 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("need positive size of 8 or greater"); 1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size = (unsigned)ret; 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* allocate memory for buffers and compression engine */ 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project blk = malloc(size + EXCESS); 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.zalloc = Z_NULL; 1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.zfree = Z_NULL; 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.opaque = Z_NULL; 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); 1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret != Z_OK || blk == NULL) 1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("out of memory"); 1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* compress from stdin until output full, or no more input */ 1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.avail_out = size + EXCESS; 1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.next_out = blk; 1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = partcompress(stdin, &def); 1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == Z_ERRNO) 1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("error reading input"); 1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if it all fit, then size was undersubscribed -- done! */ 1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { 1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* write block to stdout */ 1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = size + EXCESS - def.avail_out; 1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) 1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("error writing output"); 1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* clean up and print results to stderr */ 1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflateEnd(&def); 1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(blk); 1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, 1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project "%u bytes unused out of %u requested (all input)\n", 1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size - have, size); 1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* it didn't all fit -- set up for recompression */ 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.zalloc = Z_NULL; 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.zfree = Z_NULL; 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.opaque = Z_NULL; 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.avail_in = 0; 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.next_in = Z_NULL; 1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflateInit(&inf); 1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project tmp = malloc(size + EXCESS); 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret != Z_OK || tmp == NULL) 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("out of memory"); 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflateReset(&def); 1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* do first recompression close to the right amount */ 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.avail_in = size + EXCESS; 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.next_in = blk; 1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.avail_out = size + EXCESS; 1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.next_out = tmp; 1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = recompress(&inf, &def); 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == Z_MEM_ERROR) 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("out of memory"); 2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* set up for next reocmpression */ 2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflateReset(&inf); 2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflateReset(&def); 2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* do second and final recompression (third compression) */ 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.avail_in = size - MARGIN; /* assure stream will complete */ 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf.next_in = tmp; 2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.avail_out = size; 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project def.next_out = blk; 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = recompress(&inf, &def); 2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret == Z_MEM_ERROR) 2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("out of memory"); 2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* done -- write block to stdout */ 2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = size - def.avail_out; 2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project quit("error writing output"); 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* clean up and print results to stderr */ 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(tmp); 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflateEnd(&inf); 2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = deflateEnd(&def); 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project assert(ret != Z_STREAM_ERROR); 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project free(blk); 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(stderr, 2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project "%u bytes unused out of %u requested (%lu input)\n", 2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size - have, size, def.total_in); 2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 234