続き。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); }