3#include <gmock/gmock.h>
4#include <gtest/gtest.h>
8#include "absl/status/statusor.h"
11#define BUILD_HEADER(command, length) (command << 5) + (length - 1)
30using ::testing::ElementsAre;
31using ::testing::ElementsAreArray;
32using ::testing::TypedEq;
38 EXPECT_TRUE(load_status.ok());
39 auto compression_status = CompressV3(rom.
vector(), 0, in_size);
40 EXPECT_TRUE(compression_status.ok());
41 auto compressed_bytes = std::move(*compression_status);
42 return compressed_bytes;
46 std::vector<uint8_t>& in) {
48 EXPECT_TRUE(load_status.ok());
49 auto decompression_status = DecompressV2(rom.
data(), 0, in.size());
50 EXPECT_TRUE(decompression_status.ok());
51 auto decompressed_bytes = std::move(*decompression_status);
52 return decompressed_bytes;
57 EXPECT_TRUE(load_status.ok());
58 auto decompression_status = DecompressV2(rom.
data(), 0, in_size);
59 EXPECT_TRUE(decompression_status.ok());
60 auto decompressed_bytes = std::move(*decompression_status);
61 return decompressed_bytes;
65 const char command,
const int length,
const std::string args,
66 const int argument_length) {
67 auto new_piece = std::make_shared<CompressionPiece>(command, length, args,
69 EXPECT_TRUE(new_piece !=
nullptr);
75 const std::vector<uint8_t>& uncompressed_data,
76 const std::vector<uint8_t>& expected_compressed_data) {
77 absl::StatusOr<std::vector<uint8_t>> result =
78 CompressV3(uncompressed_data, 0, uncompressed_data.size(), 0,
false);
79 ASSERT_TRUE(result.ok());
80 auto compressed_data = std::move(*result);
81 EXPECT_THAT(compressed_data, ElementsAreArray(expected_compressed_data));
85 const std::vector<uint8_t>& expected_compressed_data) {
86 absl::StatusOr<std::vector<uint8_t>> result =
87 CompressV3(uncompressed_data, 0, uncompressed_data.size(), 0,
false);
88 EXPECT_TRUE(result.ok());
89 auto compressed_data = std::move(*result);
90 return compressed_data;
94 int leftUncompressedSize,
int repeatedByteSize,
int rightUncompressedSize) {
95 std::vector<uint8_t> result(
96 leftUncompressedSize + repeatedByteSize + rightUncompressedSize, 0);
97 std::fill_n(result.begin() + leftUncompressedSize, repeatedByteSize, 0x00);
103TEST(LC_LZ2_CompressionTest, TrivialRepeatedBytes) {
104 AssertCompressionQuality({0x00, 0x00, 0x00}, {0x22, 0x00, 0xFF});
107TEST(LC_LZ2_CompressionTest, RepeatedBytesBetweenUncompressable) {
108 AssertCompressionQuality({0x01, 0x00, 0x00, 0x00, 0x10},
109 {0x04, 0x01, 0x00, 0x00, 0x00, 0x10, 0xFF});
112TEST(LC_LZ2_CompressionTest, RepeatedBytesBeforeUncompressable) {
113 AssertCompressionQuality({0x00, 0x00, 0x00, 0x10},
114 {0x22, 0x00, 0x00, 0x10, 0xFF});
117TEST(LC_LZ2_CompressionTest, RepeatedBytesAfterUncompressable) {
118 AssertCompressionQuality({0x01, 0x00, 0x00, 0x00},
119 {0x00, 0x01, 0x22, 0x00, 0xFF});
122TEST(LC_LZ2_CompressionTest, RepeatedBytesAfterUncompressableRepeated) {
123 AssertCompressionQuality(
124 {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02},
125 {0x22, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x02, 0xFF});
128TEST(LC_LZ2_CompressionTest, RepeatedBytesBeforeUncompressableRepeated) {
129 AssertCompressionQuality(
130 {0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00},
131 {0x04, 0x01, 0x00, 0x00, 0x00, 0x02, 0x22, 0x00, 0xFF});
134TEST(LC_LZ2_CompressionTest, NewDecompressionPieceOk) {
138 int argument_length = 0x02;
141 old_piece.
length = length;
144 old_piece.
next =
nullptr;
146 auto new_piece = ExpectNewCompressionPieceOk(0x01, 0x01,
"aaa", 0x02);
148 EXPECT_EQ(old_piece.
command, new_piece->command);
149 EXPECT_EQ(old_piece.
length, new_piece->length);
152 EXPECT_EQ(old_piece.
argument[i], new_piece->argument[i]);
158TEST(LC_LZ2_CompressionTest, CompressionSingleSet) {
160 uchar single_set[5] = {0x2A, 0x2A, 0x2A, 0x2A, 0x2A};
163 auto comp_result = ExpectCompressOk(rom, single_set, 5);
164 EXPECT_THAT(single_set_expected, ElementsAreArray(comp_result.data(), 3));
167TEST(LC_LZ2_CompressionTest, CompressionSingleWord) {
169 uchar single_word[6] = {0x2A, 0x01, 0x2A, 0x01, 0x2A, 0x01};
172 auto comp_result = ExpectCompressOk(rom, single_word, 6);
173 EXPECT_THAT(single_word_expected, ElementsAreArray(comp_result.data(), 4));
176TEST(LC_LZ2_CompressionTest, CompressionSingleIncrement) {
178 uchar single_inc[3] = {0x01, 0x02, 0x03};
180 auto comp_result = ExpectCompressOk(rom, single_inc, 3);
181 EXPECT_THAT(single_inc_expected, ElementsAreArray(comp_result.data(), 3));
184TEST(LC_LZ2_CompressionTest, CompressionSingleCopy) {
186 uchar single_copy[4] = {0x03, 0x0A, 0x07, 0x14};
187 uchar single_copy_expected[6] = {
188 BUILD_HEADER(0x00, 0x04), 0x03, 0x0A, 0x07, 0x14, 0xFF};
189 auto comp_result = ExpectCompressOk(rom, single_copy, 4);
190 EXPECT_THAT(single_copy_expected, ElementsAreArray(comp_result.data(), 6));
193TEST(LC_LZ2_CompressionTest, CompressionSingleOverflowIncrement) {
194 AssertCompressionQuality({0xFE, 0xFF, 0x00, 0x01},
352TEST(HandleDirectCopyTest, NotDirectCopyWithAccumulatedBytes) {
355 context.comp_accumulator = 2;
356 HandleDirectCopy(context);
357 EXPECT_EQ(context.compressed_data.size(), 3);
360TEST(HandleDirectCopyTest, NotDirectCopyWithoutAccumulatedBytes) {
363 HandleDirectCopy(context);
364 EXPECT_EQ(context.compressed_data.size(), 2);
367TEST(HandleDirectCopyTest, AccumulateBytesWithoutMax) {
370 HandleDirectCopy(context);
371 EXPECT_EQ(context.comp_accumulator, 1);
372 EXPECT_EQ(context.compressed_data.size(), 0);
377TEST(CheckIncByteV3Test, IncreasingSequence) {
379 CheckIncByteV3(context);
380 EXPECT_EQ(context.current_cmd.data_size[kCommandIncreasingFill], 3);
383TEST(CheckIncByteV3Test, IncreasingSequenceSurroundedByIdenticalBytes) {
386 CheckIncByteV3(context);
387 EXPECT_EQ(context.current_cmd.data_size[kCommandIncreasingFill],
391TEST(CheckIncByteV3Test, NotAnIncreasingSequence) {
393 CheckIncByteV3(context);
394 EXPECT_EQ(context.current_cmd.data_size[kCommandIncreasingFill],
398TEST(LC_LZ2_CompressionTest, DecompressionValidCommand) {
400 std::vector<uint8_t> simple_copy_input = {
BUILD_HEADER(0x00, 0x02), 0x2A, 0x45, 0xFF};
401 uchar simple_copy_output[2] = {0x2A, 0x45};
402 auto decomp_result = ExpectDecompressBytesOk(rom, simple_copy_input);
403 EXPECT_THAT(simple_copy_output, ElementsAreArray(decomp_result.data(), 2));
406TEST(LC_LZ2_CompressionTest, DecompressionMixingCommand) {
419 uchar random1_o[9] = {42, 42, 42, 1, 2, 3, 4, 11, 22};
420 auto decomp_result = ExpectDecompressOk(rom, random1_i, 11);
421 EXPECT_THAT(random1_o, ElementsAreArray(decomp_result.data(), 9));
The Rom class is used to load, save, and modify Rom data.
absl::Status LoadFromBytes(const std::vector< uint8_t > &data)
absl::Status LoadFromPointer(uchar *data, size_t length, bool z3_load=true)
#define BUILD_HEADER(command, length)
constexpr int kCommandLongLength
constexpr int kCommandByteFill
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 kCommandIncreasingFill
constexpr int kCommandDirectCopy
absl::StatusOr< std::vector< uint8_t > > CompressV2(const uchar *data, const int start, const int length, int mode, bool check)
Compresses a buffer of data using the LC_LZ2 algorithm.
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uchar *data, int offset, int size, int mode)
Decompresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kCommandRepeatingBytes
constexpr int kCommandWordFill
std::vector< uint8_t > CreateRepeatedBetweenUncompressable(int leftUncompressedSize, int repeatedByteSize, int rightUncompressedSize)
std::vector< uint8_t > ExpectDecompressBytesOk(Rom &rom, std::vector< uint8_t > &in)
std::vector< uint8_t > ExpectCompressOk(Rom &rom, uchar *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 > ExpectCompressV3Ok(const std::vector< uint8_t > &uncompressed_data, const std::vector< uint8_t > &expected_compressed_data)
std::shared_ptr< CompressionPiece > ExpectNewCompressionPieceOk(const char command, const int length, const std::string args, const int argument_length)
std::vector< uint8_t > ExpectDecompressOk(Rom &rom, uchar *in, int in_size)
TEST(LC_LZ2_CompressionTest, TrivialRepeatedBytes)
std::shared_ptr< CompressionPiece > next