// Copyright 2017 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "puffin/src/sample_generator.h" #include <malloc.h> #include <zlib.h> #include <fstream> #include <iomanip> #include <iostream> #include <string> #include "puffin/src/bit_reader.h" #include "puffin/src/puff_writer.h" #include "puffin/src/set_errors.h" namespace puffin { namespace sample_generator { using std::cerr; using std::cout; using std::endl; using std::string; bool CompressToDeflate(const Buffer& uncomp, Buffer* comp, int compression, int strategy) { z_stream stream; stream.next_in = (z_const Bytef*)uncomp.data(); stream.avail_in = static_cast<unsigned int>(uncomp.size()); stream.next_out = comp->data(); stream.avail_out = comp->size(); stream.zalloc = nullptr; stream.zfree = nullptr; stream.opaque = nullptr; TEST_AND_RETURN_FALSE( Z_OK == deflateInit2(&stream, compression, Z_DEFLATED, -15, 8, strategy)); // If there was not enough output available return error. TEST_AND_RETURN_FALSE(Z_STREAM_END == deflate(&stream, Z_FINISH)); TEST_AND_RETURN_FALSE(Z_OK == deflateEnd(&stream)); comp->resize(stream.total_out); return true; } // Print an array into hex-format to the output. This can be used to create // static arrays for unit testing of the puffer/huffer. void PrintArray(const string& name, const Buffer& array) { cout << "const Buffer " << name << " = {" << endl << " "; for (size_t idx = 0; idx < array.size(); idx++) { cout << " 0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(2) << uint(array[idx]); if (idx == array.size() - 1) { cout << std::dec << "};" << endl; return; } cout << ","; if ((idx + 1) % 12 == 0) { cout << endl << " "; } } } bool PrintSample(Puffer* puffer, int compression, int strategy, const Buffer& original) { PrintArray("original", original); Buffer comp(original.size() * 4 + 10); TEST_AND_RETURN_FALSE( CompressToDeflate(original, &comp, compression, strategy)); PrintArray("compressed", comp); Buffer puff(original.size() * 3 + 10); puffin::Error error; BufferBitReader bit_reader(comp.data(), comp.size()); BufferPuffWriter puff_writer(puff.data(), puff.size()); TEST_AND_RETURN_FALSE( puffer->PuffDeflate(&bit_reader, &puff_writer, nullptr, &error)); TEST_AND_RETURN_FALSE(comp.size() == bit_reader.Offset()); puff.resize(puff_writer.Size()); PrintArray("puffed", puff); return true; } } // namespace sample_generator } // namespace puffin