3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
9#include "absl/status/statusor.h"
12#define BUILD_HEADER(command, length) (command << 5) + (length - 1)
30using ::testing::ElementsAre;
31using ::testing::ElementsAreArray;
32using ::testing::TypedEq;
37 std::vector<uint8_t> data(in, in + in_size);
39 EXPECT_TRUE(load_status.ok());
41 EXPECT_TRUE(compression_status.ok());
42 auto compressed_bytes = std::move(*compression_status);
43 return compressed_bytes;
47 std::vector<uint8_t>& in) {
49 EXPECT_TRUE(load_status.ok());
51 EXPECT_TRUE(decompression_status.ok());
52 auto decompressed_bytes = std::move(*decompression_status);
53 return decompressed_bytes;
57 std::vector<uint8_t> data(in, in + in_size);
59 EXPECT_TRUE(load_status.ok());
61 EXPECT_TRUE(decompression_status.ok());
62 auto decompressed_bytes = std::move(*decompression_status);
63 return decompressed_bytes;
67 const char command,
const int length, std::string& args,
68 const int argument_length) {
69 auto new_piece = std::make_shared<CompressionPiece>(command, length, args,
71 EXPECT_TRUE(new_piece !=
nullptr);
77 const std::vector<uint8_t>& uncompressed_data,
78 const std::vector<uint8_t>& expected_compressed_data) {
79 absl::StatusOr<std::vector<uint8_t>> result =
80 CompressV3(uncompressed_data, 0, uncompressed_data.size(), 0,
false);
81 ASSERT_TRUE(result.ok());
82 auto compressed_data = std::move(*result);
83 EXPECT_THAT(compressed_data, ElementsAreArray(expected_compressed_data));
87 const std::vector<uint8_t>& uncompressed_data,
88 const std::vector<uint8_t>& expected_compressed_data) {
89 absl::StatusOr<std::vector<uint8_t>> result =
90 CompressV3(uncompressed_data, 0, uncompressed_data.size(), 0,
false);
91 EXPECT_TRUE(result.ok());
92 auto compressed_data = std::move(*result);
93 return compressed_data;
97 int leftUncompressedSize,
int repeatedByteSize,
int rightUncompressedSize) {
98 std::vector<uint8_t> result(
99 leftUncompressedSize + repeatedByteSize + rightUncompressedSize, 0);
100 std::fill_n(result.begin() + leftUncompressedSize, repeatedByteSize, 0x00);
106TEST(LC_LZ2_CompressionTest, TrivialRepeatedBytes) {
107 AssertCompressionQuality({0x00, 0x00, 0x00}, {0x22, 0x00, 0xFF});
110TEST(LC_LZ2_CompressionTest, RepeatedBytesBetweenUncompressable) {
111 AssertCompressionQuality({0x01, 0x00, 0x00, 0x00, 0x10},
112 {0x04, 0x01, 0x00, 0x00, 0x00, 0x10, 0xFF});
115TEST(LC_LZ2_CompressionTest, RepeatedBytesBeforeUncompressable) {
116 AssertCompressionQuality({0x00, 0x00, 0x00, 0x10},
117 {0x22, 0x00, 0x00, 0x10, 0xFF});
120TEST(LC_LZ2_CompressionTest, RepeatedBytesAfterUncompressable) {
121 AssertCompressionQuality({0x01, 0x00, 0x00, 0x00},
122 {0x00, 0x01, 0x22, 0x00, 0xFF});
125TEST(LC_LZ2_CompressionTest, RepeatedBytesAfterUncompressableRepeated) {
126 AssertCompressionQuality(
127 {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02},
128 {0x22, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x02, 0xFF});
131TEST(LC_LZ2_CompressionTest, RepeatedBytesBeforeUncompressableRepeated) {
132 AssertCompressionQuality(
133 {0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00},
134 {0x04, 0x01, 0x00, 0x00, 0x00, 0x02, 0x22, 0x00, 0xFF});
137TEST(LC_LZ2_CompressionTest, NewDecompressionPieceOk) {
141 int argument_length = 0x02;
144 old_piece.
length = length;
147 old_piece.
next =
nullptr;
149 std::string new_args =
"aaa";
151 auto new_piece = ExpectNewCompressionPieceOk(0x01, 0x01, new_args, 0x02);
153 EXPECT_EQ(old_piece.
command, new_piece->command);
154 EXPECT_EQ(old_piece.
length, new_piece->length);
157 EXPECT_EQ(old_piece.
argument[i], new_piece->argument[i]);
163TEST(LC_LZ2_CompressionTest, CompressionSingleSet) {
165 uint8_t single_set[5] = {0x2A, 0x2A, 0x2A, 0x2A, 0x2A};
166 uint8_t single_set_expected[3] = {
BUILD_HEADER(1, 5), 0x2A, 0xFF};
168 auto comp_result = ExpectCompressOk(rom, single_set, 5);
169 EXPECT_THAT(single_set_expected, ElementsAreArray(comp_result.data(), 3));
172TEST(LC_LZ2_CompressionTest, CompressionSingleWord) {
174 uint8_t single_word[6] = {0x2A, 0x01, 0x2A, 0x01, 0x2A, 0x01};
175 uint8_t single_word_expected[4] = {
BUILD_HEADER(0x02, 0x06), 0x2A, 0x01, 0xFF};
177 auto comp_result = ExpectCompressOk(rom, single_word, 6);
178 EXPECT_THAT(single_word_expected, ElementsAreArray(comp_result.data(), 4));
181TEST(LC_LZ2_CompressionTest, CompressionSingleIncrement) {
183 uint8_t single_inc[3] = {0x01, 0x02, 0x03};
184 uint8_t single_inc_expected[3] = {
BUILD_HEADER(0x03, 0x03), 0x01, 0xFF};
185 auto comp_result = ExpectCompressOk(rom, single_inc, 3);
186 EXPECT_THAT(single_inc_expected, ElementsAreArray(comp_result.data(), 3));
189TEST(LC_LZ2_CompressionTest, CompressionSingleCopy) {
191 uint8_t single_copy[4] = {0x03, 0x0A, 0x07, 0x14};
192 uint8_t single_copy_expected[6] = {
193 BUILD_HEADER(0x00, 0x04), 0x03, 0x0A, 0x07, 0x14, 0xFF};
194 auto comp_result = ExpectCompressOk(rom, single_copy, 4);
195 EXPECT_THAT(single_copy_expected, ElementsAreArray(comp_result.data(), 6));
198TEST(LC_LZ2_CompressionTest, CompressionSingleOverflowIncrement) {
199 AssertCompressionQuality({0xFE, 0xFF, 0x00, 0x01},
357TEST(HandleDirectCopyTest, NotDirectCopyWithAccumulatedBytes) {
360 context.comp_accumulator = 2;
361 HandleDirectCopy(context);
362 EXPECT_EQ(context.compressed_data.size(), 3);
365TEST(HandleDirectCopyTest, NotDirectCopyWithoutAccumulatedBytes) {
368 HandleDirectCopy(context);
369 EXPECT_EQ(context.compressed_data.size(), 2);
372TEST(HandleDirectCopyTest, AccumulateBytesWithoutMax) {
375 HandleDirectCopy(context);
376 EXPECT_EQ(context.comp_accumulator, 1);
377 EXPECT_EQ(context.compressed_data.size(), 0);
382TEST(CheckIncByteV3Test, IncreasingSequence) {
384 CheckIncByteV3(context);
388TEST(CheckIncByteV3Test, IncreasingSequenceSurroundedByIdenticalBytes) {
391 CheckIncByteV3(context);
396TEST(CheckIncByteV3Test, NotAnIncreasingSequence) {
398 CheckIncByteV3(context);
403TEST(LC_LZ2_CompressionTest, DecompressionValidCommand) {
405 std::vector<uint8_t> simple_copy_input = {
BUILD_HEADER(0x00, 0x02), 0x2A,
407 uint8_t simple_copy_output[2] = {0x2A, 0x45};
408 auto decomp_result = ExpectDecompressBytesOk(rom, simple_copy_input);
409 EXPECT_THAT(simple_copy_output, ElementsAreArray(decomp_result.data(), 2));
412TEST(LC_LZ2_CompressionTest, DecompressionMixingCommand) {
425 uint8_t random1_o[9] = {42, 42, 42, 1, 2, 3, 4, 11, 22};
426 auto decomp_result = ExpectDecompressOk(rom, random1_i, 11);
427 EXPECT_THAT(random1_o, ElementsAreArray(decomp_result.data(), 9));
The Rom class is used to load, save, and modify Rom data.
absl::Status LoadFromData(const std::vector< uint8_t > &data, bool z3_load=true)
#define BUILD_HEADER(command, length)
absl::StatusOr< std::vector< uint8_t > > CompressV3(const std::vector< uint8_t > &data, const int start, const int length, int mode, bool check)
Compresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kCommandDirectCopy
constexpr int kCommandRepeatingBytes
constexpr int kCommandWordFill
constexpr int kCommandIncreasingFill
constexpr int kCommandByteFill
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uint8_t *data, int offset, int size, int mode)
Decompresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kCommandLongLength
absl::StatusOr< std::vector< uint8_t > > CompressV2(const uint8_t *data, const int start, const int length, int mode, bool check)
Compresses a buffer of data using the LC_LZ2 algorithm.
std::vector< uint8_t > CreateRepeatedBetweenUncompressable(int leftUncompressedSize, int repeatedByteSize, int rightUncompressedSize)
std::vector< uint8_t > ExpectCompressV3Ok(const std::vector< uint8_t > &uncompressed_data, const std::vector< uint8_t > &expected_compressed_data)
std::vector< uint8_t > ExpectDecompressOk(Rom &rom, uint8_t *in, int in_size)
std::shared_ptr< CompressionPiece > ExpectNewCompressionPieceOk(const char command, const int length, std::string &args, const int argument_length)
std::vector< uint8_t > ExpectCompressOk(Rom &rom, uint8_t *in, int in_size)
void AssertCompressionQuality(const std::vector< uint8_t > &uncompressed_data, const std::vector< uint8_t > &expected_compressed_data)
std::vector< uint8_t > ExpectDecompressBytesOk(Rom &rom, std::vector< uint8_t > &in)
absl::StatusOr< std::vector< uint8_t > > CompressV3(const std::vector< uint8_t > &data, const int start, const int length, int mode=1, bool check=false)
Compresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kCommandDirectCopy
constexpr int kCommandIncreasingFill
constexpr int kCommandByteFill
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uint8_t *data, int offset, int size=0x800, int mode=1)
Decompresses a buffer of data using the LC_LZ2 algorithm.
TEST(LC_LZ2_CompressionTest, TrivialRepeatedBytes)
Main namespace for the application.
unsigned int cmd_with_max
std::shared_ptr< CompressionPiece > next