/* fitblk.c: example of fitting compressed output to a specified size Notcopyrighted--providedtothepublicdomain
Version 1.1 25 November 2004 Mark Adler */
/* Version history: 1.024Nov2004Firstversion 1.125Nov2004ChangedeflateInit2()todeflateInit() Usefixed-size,stack-allocatedrawbuffers Simplifycodemovingcompressiontosubroutines Useassert()forinternalerrors Adddetaileddescriptionofapproach
*/
/* Approach to just fitting a requested compressed size:
/* compress from file to def until provided buffer is full or end of inputreached;returnlastdeflate()returnvalue,orZ_ERRNOif
there was read error on the file */
local int partcompress(FILE *in, z_streamp def)
{ int ret, flush; unsignedchar raw[RAWLEN];
flush = Z_NO_FLUSH; do {
def->avail_in = fread(raw, 1, RAWLEN, in); if (ferror(in)) return Z_ERRNO;
def->next_in = raw; if (feof(in))
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (def->avail_out != 0 && flush == Z_NO_FLUSH); return ret;
}
/* recompress from inf's input to def's output; the input for inf and theoutputfordefaresetinthosestructuresbeforecalling; returnlastdeflate()returnvalue,orZ_MEM_ERRORifinflate()
was not able to allocate enough memory when it needed to */
local int recompress(z_streamp inf, z_streamp def)
{ int ret, flush; unsignedchar raw[RAWLEN];
flush = Z_NO_FLUSH; do { /* decompress */
inf->avail_out = RAWLEN;
inf->next_out = raw;
ret = inflate(inf, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
ret != Z_NEED_DICT); if (ret == Z_MEM_ERROR) return ret;
/* compress what was decompressed until done or no room */
def->avail_in = RAWLEN - inf->avail_out;
def->next_in = raw; if (inf->avail_out != 0)
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (ret != Z_STREAM_END && def->avail_out != 0); return ret;
}
#define EXCESS 256/* empirically determined stream overage */ #define MARGIN 8/* amount to back off for completion */
/* compress from stdin to fixed-size block on stdout */ int main(int argc, char **argv)
{ int ret; /* return code */ unsigned size; /* requested fixed output block size */ unsigned have; /* bytes written by deflate() call */ unsignedchar *blk; /* intermediate and final stream */ unsignedchar *tmp; /* close to desired size stream */
z_stream def, inf; /* zlib deflate and inflate states */
/* get requested output size */ if (argc != 2)
quit("need one argument: size of output block");
ret = strtol(argv[1], argv + 1, 10); if (argv[1][0] != 0)
quit("argument must be a number"); if (ret < 8) /* 8 is minimum zlib stream size */
quit("need positive size of 8 or greater");
size = (unsigned)ret;
/* allocate memory for buffers and compression engine */
blk = malloc(size + EXCESS);
def.zalloc = Z_NULL;
def.zfree = Z_NULL;
def.opaque = Z_NULL;
ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); if (ret != Z_OK || blk == NULL)
quit("out of memory");
/* compress from stdin until output full, or no more input */
def.avail_out = size + EXCESS;
def.next_out = blk;
ret = partcompress(stdin, &def); if (ret == Z_ERRNO)
quit("error reading input");
/* if it all fit, then size was undersubscribed -- done! */ if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { /* write block to stdout */
have = size + EXCESS - def.avail_out; if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr, "%u bytes unused out of %u requested (all input)\n",
size - have, size); return0;
}
/* it didn't all fit -- set up for recompression */
inf.zalloc = Z_NULL;
inf.zfree = Z_NULL;
inf.opaque = Z_NULL;
inf.avail_in = 0;
inf.next_in = Z_NULL;
ret = inflateInit(&inf);
tmp = malloc(size + EXCESS); if (ret != Z_OK || tmp == NULL)
quit("out of memory");
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do first recompression close to the right amount */
inf.avail_in = size + EXCESS;
inf.next_in = blk;
def.avail_out = size + EXCESS;
def.next_out = tmp;
ret = recompress(&inf, &def); if (ret == Z_MEM_ERROR)
quit("out of memory");
/* set up for next recompression */
ret = inflateReset(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do second and final recompression (third compression) */
inf.avail_in = size - MARGIN; /* assure stream will complete */
inf.next_in = tmp;
def.avail_out = size;
def.next_out = blk;
ret = recompress(&inf, &def); if (ret == Z_MEM_ERROR)
quit("out of memory");
assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
/* done -- write block to stdout */
have = size - def.avail_out; if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
free(tmp);
ret = inflateEnd(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr, "%u bytes unused out of %u requested (%lu input)\n",
size - have, size, def.total_in); return0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Neuigkeiten
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.