ぬの部屋(仮)
nu-no-he-ya
  •  123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • zlibで単一のデータを圧縮( compress関数 )

    以前libpng等で使ったzlibでデータを圧縮してみる。

    圧縮時、まずcompressBound に元データのサイズを渡し、最低限その戻り値のバイト数分だけメモリを確保する。

    圧縮はcompress関数で行い、結果は第一引数で指定したメモリに書き込まれ、書き込まれたサイズは第二引数destLenに返る。

    注意点として、この関数で圧縮されたデータには元データのサイズ情報が入っていない。本来ファイル出力するのであればその情報を何らかの形で入れておくべきだが今回は画面表示して伸長プログラム側に直打ちすることにする。

    圧縮側 compress 関数使用

    int compress(
        Bytef* dest,          // 結果の格納先のバッファ
        uLongf* destLen,      // 入力:バッファサイズ ,出力:結果データサイズ
        const Bytef* source, // 元データ
        uLong sourceLen      // 元データのサイズ
    );
    

    #pragma warning(disable:4996)
    
    #include <vector>
    #include <filesystem>
    
    // 圧縮に必要
    #include <zlib.h>
    
    // 圧縮に必要
    #if _DEBUG
    #pragma comment(lib,"zlibstaticd.lib")
    #else
    #pragma comment(lib,"zlibstatic.lib")
    #endif
    
    
    //! @brief 圧縮のテスト
    //! @param [in] source 圧縮したいデータ
    //! @return 圧縮後のデータ
    std::vector< Bytef > compress_test(std::vector<unsigned char>& source) {
    
      //圧縮前のデータと
      //そのデータのサイズを準備
      unsigned char* src = source.data();
      unsigned int sourceLen = source.size();
    
    
      // compressBoundの戻り値だけメモリを確保
      uLong destLen = compressBound(sourceLen);
    
      std::vector< Bytef > dest;
      dest.resize(destLen);
    
      // compressで圧縮。
      // destLenは呼び出し時に確保したメモリ量を指定すると
      // 圧縮後の長さが帰ってくる
      int ret = compress(dest.data(), &destLen, src, sourceLen);
    
      if (ret != Z_OK) {
        return std::vector< Bytef >();
      }
    
      // 圧縮後のデータの長さがdestLenなので
      // 配列をdestLenに切り詰める
      dest.erase(dest.begin() + destLen, dest.end());
      
    
      return dest;
    }
    
    

    std::vector<
    unsigned char> read_buffer(const char* filename); int main() { // 圧縮テスト std::vector<unsigned char> buffer = read_buffer("C:/data/.cipd_client.exe"); std::vector< Bytef > cmpressed = compress_test(buffer); // ファイル書き出し FILE* fp = fopen("C:\\data\\cmp.data", "wb"); fwrite(cmpressed.data(), 1, cmpressed.size(), fp); fclose(fp); // 注意 圧縮後データには「元のファイルサイズ」が含まれない // これは、伸長時、結果を格納する領域のサイズを知ることができないことを意味する。 // 従って本来、ファイル出力時には、別途元のサイズを記録しておく必要がある。 // 今回はプログラムを複雑にしないため、画面表示してその値を手動で記録しておく。 printf("for decompress : %d bytes\n", buffer.size()); } //! @brief ファイルからデータを読み込む //! @param [in] filename ファイル名 //! @return ファイル一個分のデータ std::vector<unsigned char> read_buffer(const char* filename) { // データの準備 namespace fs = std::filesystem; std::vector<unsigned char> buffer; uintmax_t size = fs::file_size(filename); FILE* fp = fopen(filename, "rb"); buffer.resize(size); fread(buffer.data(), size, 1, fp); fclose(fp); return buffer; }
    for decompress : 18199552 bytes

    伸長側 uncompress 関数使用

    int uncompress (
        Bytef* dest,           // 伸長後のデータ格納先
        uLongf* destLen,       // 入力時:格納先のメモリサイズ 出力時:結果のメモリサイズ
        const Bytef* source,  // 圧縮されたデータ
        uLong sourceLen       // 圧縮されたデータのバイト数
    );
    

    #pragma warning(disable:4996)
    
    #include <vector>
    #include <filesystem>
    
    // 圧縮に必要
    #include <zlib.h>
    
    // 圧縮に必要
    #if _DEBUG
    #pragma comment(lib,"zlibstaticd.lib")
    #else
    #pragma comment(lib,"zlibstatic.lib")
    #endif
    
    
    
    
    //! @brief 圧縮されたデータを伸長する
    //! @param [in] compressed 圧縮されたデータ
    //! @param [in] original_size 伸長後のデータサイズ
    //! @return 伸長後のデータ
    std::vector< Bytef > uncompress_test(const std::vector<unsigned char>& compressed,const unsigned int original_size) {
    
      // 元のデータのサイズだけメモリ確保
      std::vector< Bytef > dest;
      dest.resize(original_size);
    
      //伸長
      uLongf destLen = original_size;
      int ret = uncompress(
        dest.data(), // 伸長したデータの格納先
        &destLen,  // 格納先のメモリサイズ
        compressed.data(), // 圧縮データ
        compressed.size()  // 圧縮データのサイズ
      );
    
      if (ret != Z_OK)
        return std::vector< Bytef >();
    
      return dest;
    
    }
    std::vector<unsigned char> read_buffer(const char* filename);
    
    int main()
    {
    
      std::vector<unsigned char> buffer = read_buffer("C:/data/cmp.data");
    
      // この数字は圧縮時に取得したものを指定する
      int original_filesize = 18199552;
    
      std::vector< Bytef > uncompressed = uncompress_test(buffer, original_filesize);
    
      // ファイル書き出し
      FILE* fp = fopen("C:\\data\\uncmp.data", "wb");
      fwrite(uncompressed.data(), 1, uncompressed.size(), fp);
      fclose(fp);
    
    
    }
    
    
    //! @brief ファイルからデータを読み込む
    //! @param [in] filename ファイル名
    //! @return ファイル一個分のデータ
    std::vector<unsigned char> read_buffer(const char* filename) {
      // データの準備
      namespace fs = std::filesystem;
      std::vector<unsigned char> buffer;
      uintmax_t size = fs::file_size(filename);
      FILE* fp = fopen(filename, "rb");
      buffer.resize(size);
      fread(buffer.data(), size, 1, fp);
      fclose(fp);
    
      return buffer;
    }
    

    動作確認

    .cipd_client.exeをcompressし、cmp.dataを作成した。

    cmp.dataをuncompressし、uncmp.dataを作成した。

    ちゃんと伸長できているか確認するため、コマンドプロンプトからcompコマンドでバイナリ比較する。

    zlibで単一のデータを圧縮( compress関数 )

    zlibを使って圧縮 (deflate使用)

    zlibを使って伸長 (inflate使用)