compressao_zlib.c
Upload User: syzginfo
Upload Date: 2021-02-26
Package Size: 2k
Code Size: 4k
Development Platform:

C/C++

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <assert.h>
  4. #include <zlib.h>
  5.  
  6. #define CHUNK 16384
  7.  
  8. /* Comprime de 'source' para 'dest' até o fim do buffer de arquivo
  9.    inf() retorna Z_OK caso tudo ocorra bem, Z_MEM_ERROR se a memória nao pode
  10.    ser alocada, Z_DATA_ERROR se o arquivo source contem erros(invalido ou
  11.    imcompleto), Z_STREAM_ERROR se a taxa(level) de compressao estiver indisponivel,
  12.    Z_VERSION_ERROR se a versao do cabeçalho zlib.h e a versao da biblioteca
  13.    estatica nao batem, ou Z_ERRNO se há um erro ao ler ou escrever
  14.    os arquivos */
  15.  
  16. int comprime(FILE *source, FILE *dest, int level)
  17. {
  18.     int ret, flush;
  19.     unsigned have;
  20.     z_stream strm;
  21.     unsigned char in[CHUNK];
  22.     unsigned char out[CHUNK];
  23.     strm.zalloc = Z_NULL;
  24.     strm.zfree = Z_NULL;
  25.     strm.opaque = Z_NULL;
  26.     ret = deflateInit(&strm, level);
  27.     if (ret != Z_OK)
  28.         return ret;
  29.  
  30.     /* comprime ate o fim do arquivo */
  31.     do {
  32.         strm.avail_in = fread(in, 1, CHUNK, source);
  33.         if (ferror(source)) {
  34.             (void)deflateEnd(&strm);
  35.             return Z_ERRNO;
  36.         }
  37.         flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
  38.         strm.next_in = in;
  39.         /* executa deflate() na entrada enquanto o buffer de saida nao estiver
  40.            cheio, termina compressao se 'source' tiver sido lido completamente */
  41.         do {
  42.             strm.avail_out = CHUNK;
  43.             strm.next_out = out;
  44.             ret = deflate(&strm, flush);
  45.             assert(ret != Z_STREAM_ERROR);
  46.             have = CHUNK - strm.avail_out;
  47.             if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
  48.                 (void)deflateEnd(&strm);
  49.                 return Z_ERRNO;
  50.             }
  51.         } while (strm.avail_out == 0);
  52.         assert(strm.avail_in == 0);     /* toda a entrada sera usada*/
  53.         /* done quando o ultimo dado do arquivo for processado */
  54.     } while (flush != Z_FINISH);
  55.     assert(ret == Z_STREAM_END);        /* a stream estara completa*/
  56.     /* limpa buffer e retorna */
  57.     (void)deflateEnd(&strm);
  58.     return Z_OK;
  59. }
  60.  
  61. /* Descomprime de 'source' para 'dest' até o fim do buffer de arquivo
  62.    inf() retorna Z_OK caso tudo ocorra bem, Z_MEM_ERROR se a memória nao pode
  63.    ser alocada, Z_DATA_ERROR se o arquivo source contem erros(invalido ou
  64.    imcompleto), Z_VERSION_ERROR se a versao do cabeçalho zlib.h e a versao
  65.    da biblioteca estatica nao batem, ou Z_ERRNO se há um erro ao ler ou escrever
  66.    os arquivos */
  67.  
  68. int descomprime(FILE *source, FILE *dest)
  69. {
  70.     int ret;
  71.     unsigned have;
  72.     z_stream strm;
  73.     unsigned char in[CHUNK];
  74.     unsigned char out[CHUNK];
  75.  
  76.     strm.zalloc = Z_NULL;
  77.     strm.zfree = Z_NULL;
  78.     strm.opaque = Z_NULL;
  79.     strm.avail_in = 0;
  80.     strm.next_in = Z_NULL;
  81.     ret = inflateInit(&strm);
  82.     if (ret != Z_OK)
  83.         return ret;
  84.  
  85.     do {
  86.         strm.avail_in = fread(in, 1, CHUNK, source);
  87.         if (ferror(source)) {
  88.             (void)inflateEnd(&strm);
  89.             return Z_ERRNO;
  90.         }
  91.         if (strm.avail_in == 0)
  92.             break;
  93.         strm.next_in = in;
  94.         do {
  95.             strm.avail_out = CHUNK;
  96.             strm.next_out = out;
  97.             ret = inflate(&strm, Z_NO_FLUSH);
  98.             assert(ret != Z_STREAM_ERROR);
  99.             switch (ret) {
  100.             case Z_NEED_DICT:
  101.                 ret = Z_DATA_ERROR;
  102.             case Z_DATA_ERROR:
  103.             case Z_MEM_ERROR:
  104.                 (void)inflateEnd(&strm);
  105.                 return ret;
  106.             }
  107.             have = CHUNK - strm.avail_out;
  108.             if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
  109.                 (void)inflateEnd(&strm);
  110.                 return Z_ERRNO;
  111.             }
  112.         } while (strm.avail_out == 0);
  113.         /* done quando inflate() diz q chegou o fim do arquivo */
  114.     } while (ret != Z_STREAM_END);
  115.     /* limpa buffer e retorna*/
  116.     (void)inflateEnd(&strm);
  117.     return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
  118. }