title: Determine compressed/uncompressed buffer size for Z-lib in C
body: <p>I'm using Zlib v1.2.7 to read a text file then compress it and write it to an output file. My problem is in the following example how can I determine the output buffer size based on input size? (in the example <code>gz_length</code>)
  I'm using this library for an STM32 Device. I added the unzip method and I have this problem as well for uncompressed data length.</p>
  
  <pre><code>#include "zlib.h"
  
  int unzip(unsigned char *dst, unsigned long *dst_length, unsigned char *src, unsigned long src_length)
  {
      z_stream stream;
      memset(&amp;stream, 0, sizeof(stream));
  
      stream.next_in = src;
      stream.avail_in = src_length;
  
      stream.next_out = dst;
      stream.avail_out = *dst_length;
  
      int rv = inflateInit2(&amp;stream, 15 + 16);
      if (Z_OK == rv) {
          rv = inflate(&amp;stream, Z_NO_FLUSH);
          if (Z_STREAM_END == rv) {
              inflateEnd(&amp;stream);
              rv = Z_OK;
          }
      }
  
      if (Z_OK == rv) {
          *dst_length = stream.total_out;
      } else {
          *dst_length = 0;
      }
  
      return rv;
  }
  
  
  int zip(unsigned char *dst, unsigned long *dst_length, unsigned char *src, unsigned long src_length)
  {
      z_stream        stream;
      memset(&amp;stream, 0, sizeof(stream));
  
      stream.next_in = src;
      stream.avail_in = src_length;
  
      stream.next_out = Z_NULL;
      stream.avail_out = 0;
  
      /* add 16 to MAX_WBITS to specify gzip format - it gets taken off again in defaultInit2 */
      int rv = deflateInit2(&amp;stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 16 + MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
      if (Z_OK == rv) {
          unsigned long dst_bound = deflateBound(&amp;stream, stream.avail_in) + 12; /* 12 bytes for the gzip header */
          if (dst_bound &gt; *dst_length) {
              rv = Z_MEM_ERROR;
          } else {
              stream.next_out   = dst;
              stream.avail_out = dst_bound;
          }
      }
  
      if (Z_OK == rv) {
          gz_header        header;
          memset(&amp;header, 0, sizeof(header));
          rv = deflateSetHeader(&amp;stream, &amp;header);
      }
  
      if (Z_OK == rv) {
          rv = deflate(&amp;stream, Z_FINISH);
          if (Z_STREAM_END == rv) {
              rv = deflateEnd(&amp;stream);
          }
      }
  
      if (Z_OK == rv) {
          *dst_length = stream.total_out;
      } else {
          *dst_length = 0;
      }
  
      return rv;
  }
  
  int main()
  {
      unsigned long read_size;
      unsigned char *buffer = NULL;
      unsigned char *gz_buffer = NULL;
      unsigned long input_size = 0;
  
      /* Open your_file in read-only mode */
      FILE *fp = fopen("/local/new.txt", "r");
      fseek(fp, 0, SEEK_END); /* Go to end of file */
      input_size = ftell(fp); /* How many bytes did we pass ? */
      printf("Filesize: %ld\n", input_size);
      /* Set position of stream to the beginning */
      rewind(fp);
      /* Allocate the buffer (no need to initialize it with calloc) */
      buffer = (unsigned char*) malloc((input_size + 1) * sizeof(*buffer)); /* input_size + 1 byte for the \0 */
      /* Read the file into the buffer */
      fread(buffer, input_size, 1, fp); /* Read 1 chunk of input_size bytes from fp into buffer */
      /* NULL-terminate the buffer */
      buffer[input_size] = '\0';
      /* Print it ! */
      printf("FileData: %s\n", buffer);
      fclose(fp);
      //PROBLEM HERE how to determine valid gz_length for output based on input_size
      unsigned long gz_length = input_size + 50;
      gz_buffer = (unsigned char*) malloc((gz_length) * sizeof(*gz_buffer));
  
      if (input_size &gt; 0)
      {
          int rv = zip(gz_buffer, &amp;gz_length, buffer, input_size);
          if (Z_OK == rv)
          {
              FILE *ofp = fopen("/local/out.gz", "w");
              if (ofp)
              {
                  int bw = fwrite(gz_buffer, 1, gz_length, ofp);
                  fclose(ofp);
              }
          }
          else
          {
              printf("%s:%d: %d%s", __FILE__, __LINE__, rv, newline);
          }
      }
      free(buffer);
      free(gz_buffer);
      return 0;
  }
  </code></pre>