スポンサーリンク

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

続き。inflateを使って伸長する。

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

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

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

#pragma warning(disable:4996)

#include <vector>

// 圧縮に必要
#include <zlib.h>

#include <cassert>
#include <array>

// 圧縮に必要
#if _DEBUG
#pragma comment(lib,"zlibstaticd.lib")
#else
#pragma comment(lib,"zlibstatic.lib")
#endif

constexpr int BUFFER_SIZE = 1000;


struct buffer_t {
  size_t size;
  std::array<Byte, BUFFER_SIZE> buffer;

  buffer_t(
    const size_t _size,
    const std::array<Byte, BUFFER_SIZE>& data
  ) :
    size(_size),
    buffer(data) {}
};

//! @brief ファイルからデータを読み込む
//! @param [in] filename ファイル名
//! @param [out] ファイルを読み込んだ、固定長のバッファの一覧
//! @return ファイル一個分のデータ
void read_buffer(const char* filename, std::vector< buffer_t >& datalist) {
  // データの準備
  std::array<unsigned char, BUFFER_SIZE> buffer;
  FILE* fp = fopen(filename, "rb");

  do {
    size_t readsize = fread(buffer.data(), 1, buffer.size(), fp);

    // データと読み込んだサイズを保存
    datalist.emplace_back( readsize, buffer );


  } while (feof(fp) == 0);

  fclose(fp);

}




bool my_uncompress(
  const std::vector< buffer_t >& zippedBuffer,
  std::vector< buffer_t >& data_list) {

  z_stream strm;
  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;
  strm.opaque = Z_NULL;
  strm.avail_in = 0;
  strm.next_in = Z_NULL;


  //初期化
  int ret = inflateInit(&strm);

  if (ret != Z_OK) {
    return false;
  }

  for (size_t i = 0; i < zippedBuffer.size(); i++) {

    // これから伸長するデータ。
    const buffer_t& inbuffer = zippedBuffer[i];

    strm.next_in = (Bytef*)inbuffer.buffer.data();
    strm.avail_in = (uInt)inbuffer.size;

    assert(strm.avail_in != 0);

    std::array<Byte, BUFFER_SIZE> tmpbuffer;

    do {
      strm.next_out = (Bytef*)tmpbuffer.data();// 伸長結果の書き込み先の指定
      strm.avail_out = BUFFER_SIZE;           // 書き込み先のバッファサイズ
      ret = inflate(&strm, Z_NO_FLUSH);       // 伸長
      assert((ret != Z_NEED_DICT) &&
        (ret != Z_STREAM_ERROR) &&
        (ret != Z_DATA_ERROR) &&
        (ret != Z_MEM_ERROR));

      uInt have = BUFFER_SIZE - strm.avail_out;// 展開されたデータのサイズ
      // 結果の出力先に積んでいく
      data_list.emplace_back(have, tmpbuffer);


    } while (strm.avail_out == 0);
  } while (ret != Z_STREAM_END);

// 終了字呼び出す inflateEnd(&strm); return true; }

int main()
{
  // freadで読み込むデータ一覧。
  // バッファが小さく一つの配列に収まらない状況を再現するため、
  // 小さめの領域のリストとして全てのデータを読み込む
  std::vector< buffer_t > zippedBuffer;

  // 圧縮済みデータを用意
  read_buffer("C:\\data\\cmp.data", zippedBuffer);

  std::vector< buffer_t > data_list;
  // 伸長実行
  my_uncompress(zippedBuffer, data_list);



  // ファイル書き出し
  FILE* fp = fopen("C:\\data\\uncmp.data", "wb");
  for (size_t i = 0; i < data_list.size(); i++) {
    const buffer_t& data = data_list[i];
    fwrite(data.buffer.data(), 1, data.size, fp);
  }
  fclose(fp);


}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: