2015-06-08 30 views
0

我試圖理解當我們使用字典時原始縮減的功能。我知道以下幾點。 1.當我們使用字典時,應用程序應該爲deflate()和inflate()提供相同的字典。 2.做原料放氣,這個函數必須或者叫做放氣的任何呼叫之前,或者在完成放氣塊,畢竟輸入已經被消耗和使用任何的刷新選項時,所有輸出已交付,即後Z_BLOCKZ_PARTIAL_FLUSHZ_SYNC_FLUSH,或Z_FULL_FLUSH。 (來自zlib文檔)。如何使用原始deflate/inflate使用deflate/inflate SetDictionary?

但接下來的應用程序無法解壓縮什麼是與前面相同的應用程序壓縮。壓縮和解壓縮成功,但輸入和未壓縮文件之間存在不匹配。

放氣:

do { 
     ret = deflateSetDictionary(&strm, dictionary, sizeof(dictionary)); 
     if(ret != Z_OK) { 
      fprintf(stderr, "Failed to set deflate dictionary\n"); 
      return Z_STREAM_ERROR; 
     } 
     strm.avail_in = fread(in, 1, CHUNK, source); 
     if (ferror(source)) { 
      (void)deflateEnd(&strm); 
      return Z_ERRNO; 
     } 
     flush = feof(source) ? Z_FINISH : Z_FULL_FLUSH; 
     strm.next_in = in; 

     /* run deflate() on input until output buffer not full, finish 
      compression if all of source has been read in */ 
     do { 
      strm.avail_out = CHUNK; 
      strm.next_out = out; 
      ret = deflate(&strm, flush); /* no bad return value */ 
      assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 
      have = CHUNK - strm.avail_out; 
      if (fwrite(out, 1, have, dest) != have || ferror(dest)) { 
       (void)deflateEnd(&strm); 
       return Z_ERRNO; 
      } 
     } while (strm.avail_out == 0); 
     assert(strm.avail_in == 0);  /* all input will be used */ 

     /* done when last data in file processed */ 
    } while (flush != Z_FINISH); 
    assert(ret == Z_STREAM_END);  

充氣:

do { 
     ret = inflateSetDictionary(&strm, dictionary, sizeof(dictionary)); 
     if(ret != Z_OK) { 
      fprintf(stderr, "Failed to set inflate dictionary\n"); 
      return Z_STREAM_ERROR; 
     } 
     strm.avail_in = fread(in, 1, CHUNK, source); 
     if (ferror(source)) { 
      (void)inflateEnd(&strm); 
      return Z_ERRNO; 
     } 
     if (strm.avail_in == 0) 
      break; 
     strm.next_in = in; 


     /* run inflate() on input until output buffer not full */ 
     do { 
      strm.avail_out = CHUNK; 
      strm.next_out = out; 
      ret = inflate(&strm, Z_FULL_FLUSH); 
      assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 
      switch (ret) { 
      case Z_NEED_DICT: 
       ret = Z_DATA_ERROR;  /* and fall through */ 
      case Z_DATA_ERROR: 
      case Z_MEM_ERROR: 
       (void)inflateEnd(&strm); 
       return ret; 
      } 
      have = CHUNK - strm.avail_out; 
      if (fwrite(out, 1, have, dest) != have || ferror(dest)) { 
       (void)inflateEnd(&strm); 
       return Z_ERRNO; 
      } 
     } while (strm.avail_out == 0); 

     /* done when inflate() says it's done */ 
    } while (ret != Z_STREAM_END); 

回答

1

放氣時,要設置相同的單詞每個CHUNK輸入字節。爲什麼?你應該使用deflateSetDictionary()一次,在deflateInit2()之後。從那裏開始,輸入數據本身應該比您可能提供的字典更好地匹配字符串。

在膨脹的一面,你將不得不知道壓縮塊的結束位置,這樣你可以在壓縮時完全相同的位置執行inflateSetDictionary()。這將需要某種標記,計數或搜索完全沖洗模式。

+0

感謝您的回答。我爲每個CHUNK輸入字節調用deflateSetdictionary()僅用於實驗目的。無論如何,我在你的答案的後半部分已經澄清了我的問題。 – Chinna